__getattr__ question

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Laszlo Nagy

    #1

    __getattr__ question


    Hello,

    This is from the Python documentation (fragment):

    __getattr__( self, name)
    Called when an attribute lookup has not found the attribute in the
    usual places (i.e. it is not an instance attribute nor is it found in
    the class tree for self). name is the attribute name. This method should
    return the (computed) attribute value or raise an AttributeError exception.


    How can I determine if an attribute can be found in the usual places?
    Here is an example program that will enlight the basic problem.

    class TemplateItem(ob ject):
    def __init__(self,n ame):
    self.name = name
    self.items = [] # Order of items is important
    def __getattr__(sel f,name):
    """I would like to access the items easily, with their name (if
    possible)"""
    for item in self.items:
    if hasattr(item,'n ame') and item.name == name:
    return item
    raise AttributeError( "%s: attribute or item does not exists."%name)
    def __str__(self):
    return "TemplateItem(' %s')"%self.name

    class CustomTemplateI tem(TemplateIte m):
    pass # I could have been customized this...


    root = CustomTemplateI tem('root')
    i1 = CustomTemplateI tem('item1')
    i2 = CustomTemplateI tem('item2')

    root.items.appe nd(i1)
    root.items.appe nd(i2)
    TemplateItem.it em3 = TemplateItem('i tem3')

    print root
    print root.item1
    print root.item2
    print root.item3

    Of course this program will print:

    TemplateItem('r oot')
    TemplateItem('i tem1')
    TemplateItem('i tem2')
    TemplateItem('i tem3')

    So how can I tell if 'root.item3' COULD BE FOUND IN THE USUAL PLACES, or
    if it is something that was calculated by __getattr__ ?
    Of course technically, this is possible and I could give a horrible
    method that tells this...
    But is there an easy, reliable and thread safe way in the Python
    language to give the answer?

    Thanks,

    Laszlo

  • Ben Cartwright

    #2
    Re: __getattr__ question

    Laszlo Nagy wrote:[color=blue]
    > So how can I tell if 'root.item3' COULD BE FOUND IN THE USUAL PLACES, or
    > if it is something that was calculated by __getattr__ ?
    > Of course technically, this is possible and I could give a horrible
    > method that tells this...
    > But is there an easy, reliable and thread safe way in the Python
    > language to give the answer?[/color]

    Why are you trying to do this in the first place? If you need to
    distinguish between a "real" attribute and something your code returns,
    you shouldn't mix them by defining __getattr__ to begin with.

    If, as I suspect, you just want an easy way of accessing child objects
    by name, why not rename "__getattr_ _" in your code to something like
    "get"?

    Then instead of[color=blue][color=green][color=darkred]
    >>> root.item3[/color][/color][/color]
    Use[color=blue][color=green][color=darkred]
    >>> root.get('item3 ')[/color][/color][/color]

    Alternately, make self.items an instance of a custom class with
    __getattr__ defined. This way, root's attribute space won't be
    cluttered up.[color=blue][color=green][color=darkred]
    >>> root.items.item 3[/color][/color][/color]

    Either way is a few more characters to type, but it's far saner than
    trying to distinguish between "real" and "fake" attributes.

    --Ben

    Comment

    • Laszlo Nagy

      #3
      Re: __getattr__ question

      [color=blue]
      >
      > Either way is a few more characters to type, but it's far saner than
      > trying to distinguish between "real" and "fake" attributes.
      >[/color]
      I think you are right. I'll make up my mind.

      Comment

      • gotletter@gmail.com

        #4
        Re: __getattr__ question

        Hello!
        [color=blue]
        > How can I determine if an attribute can be found in the usual places?[/color]

        print "item1" in dir(root) # False
        print "item3" in dir(root) # True

        Is it the behavior you wanted?

        Comment

        • gotletter@gmail.com

          #5
          Re: __getattr__ question

          And yes, it is more to type ;)

          Comment

          • Laszlo Nagy

            #6
            Re: __getattr__ question

            [color=blue]
            > print "item1" in dir(root) # False
            > print "item3" in dir(root) # True
            >
            > Is it the behavior you wanted?
            >[/color]
            Exactly. :-) Why I did not think of this?

            I'm always amazed when I see that Python can do anything we want. :-)

            Comment

            Working...