Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

pyhton basic query (passing to classes)

Options
  • 03-03-2017 10:53am
    #1
    Moderators, Arts Moderators Posts: 35,258 Mod ✭✭✭✭


    Sorry for the noob question but I'm just not getting this simple thing no matter how many tutorials and stackexchange questions I read.

    I have class A with a string (an OLEDB connection string FWIW).
    I call a class B to display an edit box, showing this string, allowing the user to edit and save it. The next time class B is called, it should display this updated string.

    I tried the following:

    assign the first string in class A with self.mystring = 'something'
    call class B with no arguments
    ask class B to display self.mystring
    result: class B does not know self.mystring

    call class B with argument self.mystring
    add self.mystring as a parameter of def _init_ in class B
    result: syntax error in the init function declaration

    call class B with argument self.mystring
    add mystring as a parameter of def _init_ in class B
    display mystring for the user to edit to 'something_else'
    result: the string 'something' is displayed and the edited string 'something_else' is printed to but on the next call to class B 'something' is displayed

    How, apart from using global variables, should I pass a string to a class and get it back, edited?


Comments

  • Registered Users Posts: 6,120 ✭✭✭Talisman


    From what you have described you want 'mystring' to be globally accessible. Are you familiar with the Singleton pattern?

    A simple implementation in Python 3:
    class Singleton:
    
        __only_me = None
    
        def __init__(self):
            if not Singleton.__only_me:
                # your initial values go here
                self.s = "Hello world!"
            else:
                raise RuntimeError('A Singleton already exists')
    
        @classmethod
        def getInstance(cls):
            if not cls.__only_me:
                cls.__only_me = Singleton()
            return cls.__only_me
    
    # A and B reference the same Singleton object
    A = Singleton.getInstance()
    B = Singleton.getInstance()
    
    # Change "Hello world!" to "Hi mom!" in object A
    A.s = "Hi mom!"
    
    # Display the value stored in object B
    print(B.s) # Hi mom!
    


  • Registered Users Posts: 2,020 ✭✭✭Colonel Panic


    A singleton is just an enterprise global variable.

    To the OP, how about passing Class A to Class B all the time? Class A has the connection string so B just display it in either an empty or set state.


  • Moderators, Arts Moderators Posts: 35,258 Mod ✭✭✭✭pickarooney


    A singleton is just an enterprise global variable.

    To the OP, how about passing Class A to Class B all the time? Class A has the connection string so B just display it in either an empty or set state.

    How do I pass the entire class to B? I thought that the 'parent' parameter in the class definition was supposed to do that, but I think I've misunderstood it.


  • Registered Users Posts: 2,020 ✭✭✭Colonel Panic


    How do I pass the entire class to B? I thought that the 'parent' parameter in the class definition was supposed to do that, but I think I've misunderstood it.

    My wording wasn't great. You should pass an instance of the class via the other class' constructor.


  • Registered Users Posts: 768 ✭✭✭14ned


    My wording wasn't great. You should pass an instance of the class via the other class' constructor.

    Python is unusual compared to other languages in that variables are bindings to things rather than being things directly. So

    a = Foo() # a is bound to a Foo instance
    b = a # doesn't make a copy, binds also to the same Foo instance
    c = a[:] # makes an actual copy of Foo
    c = b # throw away the copy just made, rebind to the first Foo instance

    In Python therefore it is always efficient to pass stuff around by value because everything is always by reference.

    Not all languages are like this, but most of the newer ones like Python are.

    Niall


  • Advertisement
  • Registered Users Posts: 2,020 ✭✭✭Colonel Panic


    >>> class Foo(object):
    ...     pass
    ...
    >>> foo = Foo()
    >>> foo
    <__main__.Foo object at 0x76a1f910>
    >>> fooCopy = foo[:]
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'Foo' object has no attribute '__getitem__'
    

    You suggest using array slicing syntax to copy an object, not a list.


  • Moderators, Arts Moderators Posts: 35,258 Mod ✭✭✭✭pickarooney


    My wording wasn't great. You should pass an instance of the class via the other class' constructor.

    All working OK like this now. Initially, the properties of the class B were not being recognised when I called an instance of it in class A as I had both a self and non-self version of the variable and the self one was only declared inside a function of the class. Initialising it outside that function made it work.

    So, now that it's all done, what's everyone's preferred method of distributing a python program to users who won't have python installed? I've tried compiling with Cx_Freeze and pyinstaller but neither of the generated EXEs will run on the destination PC without python.


  • Registered Users Posts: 2,020 ✭✭✭Colonel Panic


    Glad passing the object worked. No idea about the other query to be honest!


Advertisement