__dict__ for instances?

Discussion in 'Python' started by Ivan Voras, May 13, 2007.

  1. Ivan Voras

    Ivan Voras Guest

    While using PyGTK, I want to try and define signal handlers
    automagically, without explicitly writing the long dictionary (i.e. I
    want to use signal_autoconnect()).

    To do this, I need something that will inspect the current "self" and
    return a dictionary that looks like:

    {
    "method_name" : self.method_name
    }

    Class.__dict__ does something very similar, but when I use it, either
    I'm doing something wrong or it doesn't return methods bound to "self",
    and python complains a wrong number of arguments is being passed to the
    methods (one instead of two).

    instance.__dict__ on the other hand returns an empty dictionary.

    This looks like it should be easy, but I can't find the solution :(

    --
    (\__/)
    (o_O)
    (> < )

    This is Bunny.
    Copy Bunny into your signature to help him on his way to world domination!


    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.4 (MingW32)
    Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

    iD8DBQFGRlnFldnAQVacBcgRAugIAJ0aqM6ZNKeUZUFCur7ODEbGcMFvCgCgxze2
    LCUqdGi4nCvZrwnFru2To6Y=
    =+8Zd
    -----END PGP SIGNATURE-----
    Ivan Voras, May 13, 2007
    #1
    1. Advertising

  2. Ivan Voras

    Guest

    On May 12, 5:20 pm, Ivan Voras <ivoras@__fer.hr__> wrote:
    > While using PyGTK, I want to try and define signal handlers
    > automagically, without explicitly writing the long dictionary (i.e. I
    > want to use signal_autoconnect()).
    >
    > To do this, I need something that will inspect the current "self" and
    > return a dictionary that looks like:
    >
    > {
    > "method_name" : self.method_name
    >
    > }
    >
    > Class.__dict__ does something very similar, but when I use it, either
    > I'm doing something wrong or it doesn't return methods bound to "self",
    > and python complains a wrong number of arguments is being passed to the
    > methods (one instead of two).
    >
    > instance.__dict__ on the other hand returns an empty dictionary.
    >
    > This looks like it should be easy, but I can't find the solution :(
    >
    > --
    > (\__/)
    > (o_O)
    > (> < )
    >
    > This is Bunny.
    > Copy Bunny into your signature to help him on his way to world domination!
    >
    > signature.asc
    > 1KDownload


    I think you want "dir(instance)" __dict__ returns the instance
    variables and values as a dictionary, but doesn't return methods.
    dir() returns a list of the instance's methods and variables. Then
    you'd need to iterate over the list with type() looking for instance
    methods

    instance = Class.Class()
    dict = {}
    methods = [f for f in dir(instance) if str(type(instance.f)) == "<type
    'instancemethod'>"]
    for m in methods:
    dict[m.name] = m

    The above is untested. I'm sure there is a better way to do this.

    ~Sean
    , May 13, 2007
    #2
    1. Advertising

  3. Ivan Voras

    Ivan Voras Guest

    wrote:

    > I think you want "dir(instance)" __dict__ returns the instance


    Part of the problem is that dir(instance) returns a list of strings, so
    iterating the dir(instance) gets me strings, not methods. Alternatively,
    is there a way to get a "bound" instance by its name - some
    introspection function perhaps?

    > variables and values as a dictionary, but doesn't return methods.


    It does on a Class :(

    --
    (\__/)
    (o_O)
    (> < )

    This is Bunny.
    Copy Bunny into your signature to help him on his way to world domination!


    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.4 (MingW32)
    Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

    iD8DBQFGRvbdldnAQVacBcgRAvtoAJ46Z2Tkwo+MS6khyh9UZ4w2vqbccQCg11yr
    SbMsN4ezb8lWw3Yz3evcDAc=
    =dxlb
    -----END PGP SIGNATURE-----
    Ivan Voras, May 13, 2007
    #3
  4. Ivan Voras a écrit :
    > wrote:
    >
    >
    >>I think you want "dir(instance)" __dict__ returns the instance

    >
    >
    > Part of the problem is that dir(instance) returns a list of strings, so
    > iterating the dir(instance) gets me strings, not methods. Alternatively,
    > is there a way to get a "bound" instance by its name - some
    > introspection function perhaps?


    getattr(obj, name)

    >
    >>variables and values as a dictionary, but doesn't return methods.

    >
    >
    > It does on a Class :(
    >

    Usually, methods are attributes of the class, not of the instance.
    Bruno Desthuilliers, May 13, 2007
    #4
  5. Ivan Voras a écrit :
    > While using PyGTK, I want to try and define signal handlers
    > automagically, without explicitly writing the long dictionary (i.e. I
    > want to use signal_autoconnect()).
    >
    > To do this, I need something that will inspect the current "self" and
    > return a dictionary that looks like:
    >
    > {
    > "method_name" : self.method_name
    > }
    >
    > Class.__dict__ does something very similar, but when I use it, either
    > I'm doing something wrong or it doesn't return methods bound to "self",
    > and python complains a wrong number of arguments is being passed to the
    > methods (one instead of two).


    You're not doing anything wrong, that's just how Python works. "methods"
    are wrapper objects around function objects attributes. The wrapping
    only happens at lookup time, and returns different kind of "method"
    wrapper (resp. unbound or bound methods) if the attribute is looked up
    on an instance or a class (there are also the staticmethod/classmethod
    things, but that's not your problem here).

    You can build the dict you're looking for using dir() and getattr():

    from types import MethodType

    autoconnect_dict = {}
    for name in dir(self):
    attr = getattr(self, name)
    if isinstance(attr, MethodType):
    autoconnect_dict[name] = attr
    return autoconnect_dict


    > instance.__dict__ on the other hand returns an empty dictionary.


    the instance's __dict__ only stores per-instance attributes. While it's
    technically possible to attach methods per-instance, it's definitively a
    corner case.
    Bruno Desthuilliers, May 13, 2007
    #5
  6. Ivan Voras <ivoras@__fer.hr__> scribis:
    > While using PyGTK, I want to try and define signal handlers
    > automagically, without explicitly writing the long dictionary (i.e. I
    > want to use signal_autoconnect()).
    >
    > To do this, I need something that will inspect the current "self" and
    > return a dictionary that looks like:
    >
    > {
    > "method_name" : self.method_name
    > }


    Nope, at least for PyGTK 2 :) See below.

    [...]
    > This looks like it should be easy, but I can't find the solution :(


    Use the doc, Luke, oops, Ivan :)
    Citing the gtk.glade.XML.signal_autoconnect documentation:
    def signal_autoconnect(dict)
    dict: a mapping or an instance
    ^^^^^^^^

    The signal_autoconnect() method is a variation of the
    gtk.glade.XML.signal_connect method. It uses Python's introspective
    features to look at the keys (if dict is a mapping) or attributes (if
    ^^^^^^^^^^^^^^
    dict is an instance) and tries to match them with the signal handler
    ^^^^^^^^^^^^^^^^^^^
    names given in the interface description. The callbacks referenced by
    each matched key or attribute are connected to their matching signals.
    The argument is called dict due to compatibility reasons since
    originally only the mapping interface was supported. The instance
    variant was introduced in PyGTK 2.0.

    So simply using signal_autoconnect(self) should work.

    AdiaÅ­, Marc
    Marc Christiansen, May 13, 2007
    #6
  7. Ivan Voras

    Guest

    On May 13, 4:30 am, Ivan Voras <ivoras@__fer.hr__> wrote:
    > wrote:
    > > I think you want "dir(instance)" __dict__ returns the instance

    >
    > Part of the problem is that dir(instance) returns a list of strings, so
    > iterating the dir(instance) gets me strings, not methods. Alternatively,
    > is there a way to get a "bound" instance by its name - some
    > introspection function perhaps?
    >
    > > variables and values as a dictionary, but doesn't return methods.

    >
    > It does on a Class :(
    >
    > --
    > (\__/)
    > (o_O)
    > (> < )
    >
    > This is Bunny.
    > Copy Bunny into your signature to help him on his way to world domination!
    >
    > signature.asc
    > 1KDownload


    I tried.

    ~Sean
    , May 13, 2007
    #7
  8. Ivan Voras

    Ivan Voras Guest

    Marc Christiansen wrote:

    > Nope, at least for PyGTK 2 :) See below.


    Aaah, but....!

    > [...]
    >> This looks like it should be easy, but I can't find the solution :(

    >
    > Use the doc, Luke, oops, Ivan :)
    > Citing the gtk.glade.XML.signal_autoconnect documentation:
    > def signal_autoconnect(dict)
    > dict: a mapping or an instance
    > ^^^^^^^^


    I should have mentioned - I tried it already and it didn't work. The
    specific error I get is:

    "WARNING: "on_button_clicked" not callable or a tuple"

    once for each handler when I call autoconnect. And I've got a recent
    version of pyGTK (2.10.4) so it should.


    --
    (\__/)
    (o_O)
    (> < )

    This is Bunny.
    Copy Bunny into your signature to help him on his way to world domination!


    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.4 (MingW32)
    Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

    iD8DBQFGR0jOldnAQVacBcgRAvHqAKCdYJxSmCqvyrBXVTPQMc50R5KsMwCfULkH
    jpSJzgL8qBJRaQIP8xKQrXA=
    =SsEg
    -----END PGP SIGNATURE-----
    Ivan Voras, May 13, 2007
    #8
  9. Ivan Voras

    Ivan Voras Guest

    Bruno Desthuilliers wrote:

    > You're not doing anything wrong, that's just how Python works. "methods"
    > are wrapper objects around function objects attributes. The wrapping
    > only happens at lookup time, and returns different kind of "method"
    > wrapper (resp. unbound or bound methods) if the attribute is looked up
    > on an instance or a class (there are also the staticmethod/classmethod
    > things, but that's not your problem here).


    Got it, thanks for the explanation!



    --
    (\__/)
    (o_O)
    (> < )

    This is Bunny.
    Copy Bunny into your signature to help him on his way to world domination!


    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.4 (MingW32)
    Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

    iD8DBQFGR0kPldnAQVacBcgRAls/AJ9vyGQG9Hvasr0Qex5gTl+wDD3gTgCeNBo0
    GQNo30dEuhwVZaxfHitgBv4=
    =8ZXE
    -----END PGP SIGNATURE-----
    Ivan Voras, May 13, 2007
    #9
  10. Ivan Voras a écrit :
    > Marc Christiansen wrote:
    >
    >
    >>Nope, at least for PyGTK 2 :) See below.

    >
    >
    > Aaah, but....!
    >
    >
    >>[...]
    >>
    >>>This looks like it should be easy, but I can't find the solution :(

    >>
    >>Use the doc, Luke, oops, Ivan :)
    >>Citing the gtk.glade.XML.signal_autoconnect documentation:
    >> def signal_autoconnect(dict)
    >> dict: a mapping or an instance
    >> ^^^^^^^^

    >
    >
    > I should have mentioned - I tried it already and it didn't work. The
    > specific error I get is:
    >
    > "WARNING: "on_button_clicked" not callable or a tuple"


    Please post the relevant code and the full traceback.
    Bruno Desthuilliers, May 13, 2007
    #10
  11. Ivan Voras

    Ivan Voras Guest

    Bruno Desthuilliers wrote:

    >> "WARNING: "on_button_clicked" not callable or a tuple"

    >
    > Please post the relevant code and the full traceback.


    The code:

    Class W:
    def __init__(self):
    self.xml = gtk.glade.XML("glade/mainwin.glade")
    self.window = self.xml.get_widget("mainwin")
    self.xml.signal_autoconnect(self)

    w = W()
    gtk.main()

    The error (not an exception, only the message appears and the handler
    doesn't work):

    ** (finstall.py:7551): WARNING **: handler for 'on_button_next_clicked'
    not callable or a tuple

    (the file has some 20 lines, not 7551)


    --
    (\__/)
    (o_O)
    (> < )

    This is Bunny.
    Copy Bunny into your signature to help him on his way to world domination!


    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.4 (MingW32)
    Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

    iD8DBQFGR5XqldnAQVacBcgRAu7xAJ9COrvqgow1O0gcK6F+AS7rfu/AlwCg3rnI
    fVb71HKuapkbaE+cwt+4JT0=
    =2of5
    -----END PGP SIGNATURE-----
    Ivan Voras, May 13, 2007
    #11
  12. Ivan Voras a écrit :
    > Bruno Desthuilliers wrote:
    >
    >>> "WARNING: "on_button_clicked" not callable or a tuple"

    >> Please post the relevant code and the full traceback.

    >
    > The code:
    >
    > Class W:
    > def __init__(self):
    > self.xml = gtk.glade.XML("glade/mainwin.glade")
    > self.window = self.xml.get_widget("mainwin")
    > self.xml.signal_autoconnect(self)
    >
    > w = W()
    > gtk.main()
    >
    > The error (not an exception, only the message appears and the handler
    > doesn't work):
    >
    > ** (finstall.py:7551): WARNING **: handler for 'on_button_next_clicked'
    > not callable or a tuple


    Is this the full message, or did you skip the preceding lines ?

    > (the file has some 20 lines, not 7551)
    >

    Is "finstall.py" the name of your file ? If yes, I'd suspect something
    wrong with your sys.path or like...
    Bruno Desthuilliers, May 14, 2007
    #12
  13. Ivan Voras

    Ivan Voras Guest

    Bruno Desthuilliers wrote:

    >> The error (not an exception, only the message appears and the handler
    >> doesn't work):
    >>
    >> ** (finstall.py:7551): WARNING **: handler for 'on_button_next_clicked'
    >> not callable or a tuple

    >
    > Is this the full message, or did you skip the preceding lines ?


    The full message.

    >> (the file has some 20 lines, not 7551)
    >>

    > Is "finstall.py" the name of your file ? If yes, I'd suspect something
    > wrong with your sys.path or like...


    This is the name of my file - and it IS executed, only the error message
    is weird.


    --
    (\__/)
    (o_O)
    (> < )

    This is Bunny.
    Copy Bunny into your signature to help him on his way to world domination!


    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.4 (MingW32)
    Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

    iD8DBQFGWKULldnAQVacBcgRArdiAKDhp9tGfknLb9xoSFLZeFMrj3Cq4wCgk8ET
    qq91Y8nFcjyC7545MaAtwM4=
    =2lug
    -----END PGP SIGNATURE-----
    Ivan Voras, May 26, 2007
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ed Young
    Replies:
    4
    Views:
    322
    Ed Young
    Aug 10, 2003
  2. Replies:
    1
    Views:
    329
    Alex Martelli
    Nov 6, 2003
  3. John Wohlbier
    Replies:
    2
    Views:
    358
    Josiah Carlson
    Feb 22, 2004
  4. Derek Fountain

    When is a __dict__ not a __dict__?

    Derek Fountain, Apr 21, 2004, in forum: Python
    Replies:
    1
    Views:
    323
    John Roth
    Apr 21, 2004
  5. Replies:
    8
    Views:
    446
    James Stroud
    Jan 29, 2009
Loading...

Share This Page