How to customize getattr(obj, prop) function ?

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

    How to customize getattr(obj, prop) function ?

    Hi,

    Sorry in advance, english is not my main language :/

    I'd like to customize the result obtained by getattr on an object : if
    the object has the requested property then return it BUT if the object
    doesn't has actually this property return something else.

    In my case, I can't use getattr(object, property, default_value).

    I tried to write a class with a __getattr__ method and even a
    __getattribute_ _ method but this doesn't do what I want....

    Maybe I didn't correctly understand this :


    Here is a piece of my code :
    =============== =============== =======
    class myclass:
    """docstrin g"""

    a = 'aa'
    b = 'bb'

    def __getattr___(se lf, ppt):
    """getattr" ""
    if hasattr(self, ppt):
    return self.ppt
    else:
    return "my custom computed result"

    def __getattribute_ _(self, ppt):
    """getattribute """
    if hasattr(self, ppt):
    return self.ppt
    else:
    return "my custom computed result"

    if __name__ == "__main__":

    d = myclass()
    p1 = getattr(d, "a")
    print p1
    p2 = getattr(d, "b")
    print p2
    p3 = getattr(d, "c")
    print p3
    =============== =============== ==

    I get an AttributeError when accessing to the property named "c".

    Any explanation/solution to my problem ?

  • Richard Copeland

    #2
    Re: How to customize getattr(obj, prop) function ?


    Try this:

    class Class:
    a='aa'
    b='bb'
    def __getattr__(sel f, ppt):
    return 'custom computed result'

    __getattr__ is only called when "normal" attribute lookup fails, so
    there's no need for the "hasattr" test.

    Also, I believe that __getattribute_ _ only applies to new-style classes
    (classes derived from "object"), and it will override *all* attribute
    accesses, anyway (meaning you'd have infinite recursion if you used it
    since you look up "self.ppt")

    Pierre wrote:[color=blue]
    > Hi,
    >
    > Sorry in advance, english is not my main language :/
    >
    > I'd like to customize the result obtained by getattr on an object : if
    > the object has the requested property then return it BUT if the object
    > doesn't has actually this property return something else.
    >
    > In my case, I can't use getattr(object, property, default_value).
    >
    > I tried to write a class with a __getattr__ method and even a
    > __getattribute_ _ method but this doesn't do what I want....
    >
    > Maybe I didn't correctly understand this :
    > http://docs.python.org/ref/attribute-access.html
    >
    > Here is a piece of my code :
    > =============== =============== =======
    > class myclass:
    > """docstrin g"""
    >
    > a = 'aa'
    > b = 'bb'
    >
    > def __getattr___(se lf, ppt):
    > """getattr" ""
    > if hasattr(self, ppt):
    > return self.ppt
    > else:
    > return "my custom computed result"
    >
    > def __getattribute_ _(self, ppt):
    > """getattribute """
    > if hasattr(self, ppt):
    > return self.ppt
    > else:
    > return "my custom computed result"
    >
    > if __name__ == "__main__":
    >
    > d = myclass()
    > p1 = getattr(d, "a")
    > print p1
    > p2 = getattr(d, "b")
    > print p2
    > p3 = getattr(d, "c")
    > print p3
    > =============== =============== ==
    >
    > I get an AttributeError when accessing to the property named "c".
    >
    > Any explanation/solution to my problem ?
    >[/color]

    Comment

    • Richard Copeland

      #3
      Re: How to customize getattr(obj, prop) function ?

      Try this:

      class Class:
      a='aa'
      b='bb'
      def __getattr__(sel f, ppt):
      return 'custom computed result'

      __getattr__ is only called when "normal" attribute lookup fails, so
      there's no need for the "hasattr" test.

      Also, I believe that __getattribute_ _ only applies to new-style classes
      (classes derived from "object"), and it will override *all* attribute
      accesses, anyway (meaning you'd have infinite recursion if you used it
      since you look up "self.ppt")

      Pierre wrote:[color=blue]
      > Hi,
      >
      > Sorry in advance, english is not my main language :/
      >
      > I'd like to customize the result obtained by getattr on an object : if
      > the object has the requested property then return it BUT if the object
      > doesn't has actually this property return something else.
      >
      > In my case, I can't use getattr(object, property, default_value).
      >
      > I tried to write a class with a __getattr__ method and even a
      > __getattribute_ _ method but this doesn't do what I want....
      >
      > Maybe I didn't correctly understand this :
      > http://docs.python.org/ref/attribute-access.html
      >
      > Here is a piece of my code :
      > =============== =============== =======
      > class myclass:
      > """docstrin g"""
      >
      > a = 'aa'
      > b = 'bb'
      >
      > def __getattr___(se lf, ppt):
      > """getattr" ""
      > if hasattr(self, ppt):
      > return self.ppt
      > else:
      > return "my custom computed result"
      >
      > def __getattribute_ _(self, ppt):
      > """getattribute """
      > if hasattr(self, ppt):
      > return self.ppt
      > else:
      > return "my custom computed result"
      >
      > if __name__ == "__main__":
      >
      > d = myclass()
      > p1 = getattr(d, "a")
      > print p1
      > p2 = getattr(d, "b")
      > print p2
      > p3 = getattr(d, "c")
      > print p3
      > =============== =============== ==
      >
      > I get an AttributeError when accessing to the property named "c".
      >
      > Any explanation/solution to my problem ?
      >[/color]

      Comment

      • Richard Copeland

        #4
        Re: How to customize getattr(obj, prop) function ?

        Try this:

        class Class:
        a='aa'
        b='bb'
        def __getattr__(sel f, ppt):
        return 'custom computed result'

        __getattr__ is only called when "normal" attribute lookup fails, so
        there's no need for the "hasattr" test.

        Also, I believe that __getattribute_ _ only applies to new-style classes
        (classes derived from "object"), and it will override *all* attribute
        accesses, anyway (meaning you'd have infinite recursion if you used it
        since you look up "self.ppt")

        Pierre wrote:[color=blue]
        > Hi,
        >
        > Sorry in advance, english is not my main language :/
        >
        > I'd like to customize the result obtained by getattr on an object : if
        > the object has the requested property then return it BUT if the object
        > doesn't has actually this property return something else.
        >
        > In my case, I can't use getattr(object, property, default_value).
        >
        > I tried to write a class with a __getattr__ method and even a
        > __getattribute_ _ method but this doesn't do what I want....
        >
        > Maybe I didn't correctly understand this :
        > http://docs.python.org/ref/attribute-access.html
        >
        > Here is a piece of my code :
        > =============== =============== =======
        > class myclass:
        > """docstrin g"""
        >
        > a = 'aa'
        > b = 'bb'
        >
        > def __getattr___(se lf, ppt):
        > """getattr" ""
        > if hasattr(self, ppt):
        > return self.ppt
        > else:
        > return "my custom computed result"
        >
        > def __getattribute_ _(self, ppt):
        > """getattribute """
        > if hasattr(self, ppt):
        > return self.ppt
        > else:
        > return "my custom computed result"
        >
        > if __name__ == "__main__":
        >
        > d = myclass()
        > p1 = getattr(d, "a")
        > print p1
        > p2 = getattr(d, "b")
        > print p2
        > p3 = getattr(d, "c")
        > print p3
        > =============== =============== ==
        >
        > I get an AttributeError when accessing to the property named "c".
        >
        > Any explanation/solution to my problem ?
        >[/color]

        Comment

        • Pierre

          #5
          Re: How to customize getattr(obj, prop) function ?

          Nop I get the same AttributeError when I try to access to the property
          "c"...

          Comment

          • George Sakkis

            #6
            Re: How to customize getattr(obj, prop) function ?

            Pierre wrote:
            [color=blue]
            > Hi,
            >
            > Sorry in advance, english is not my main language :/
            >
            > I'd like to customize the result obtained by getattr on an object : if
            > the object has the requested property then return it BUT if the object
            > doesn't has actually this property return something else.
            >
            > In my case, I can't use getattr(object, property, default_value).
            >
            > I tried to write a class with a __getattr__ method and even a
            > __getattribute_ _ method but this doesn't do what I want....
            >
            > Maybe I didn't correctly understand this :
            > http://docs.python.org/ref/attribute-access.html
            >
            > Here is a piece of my code :
            > =============== =============== =======
            > class myclass:
            > """docstrin g"""
            >
            > a = 'aa'
            > b = 'bb'
            >
            > def __getattr___(se lf, ppt):
            > """getattr" ""
            > if hasattr(self, ppt):
            > return self.ppt
            > else:
            > return "my custom computed result"[/color]

            1) You have misspelled the method by adding a hard-to-spot third
            trailing underscore.
            2) __getattr__ is called when normal lookup fails, so the condition
            evaluates always to False.
            [color=blue]
            > def __getattribute_ _(self, ppt):
            > """getattribute """
            > if hasattr(self, ppt):
            > return self.ppt
            > else:
            > return "my custom computed result"[/color]

            1) __getattribute_ _ is called for new-style classes only (those that
            inherit directly or indirectly from object).
            2) Even if your class was new-style, this would enter an infinite loop
            because 'self.ppt' calls __getattribute_ _ again.

            George

            Comment

            • Richard Copeland

              #7
              Re: How to customize getattr(obj, prop) function ?

              I tested the exact code I sent you on python 2.4.1. What version of
              Python are you using?

              Thanks,
              Rick

              Pierre wrote:[color=blue]
              > Nop I get the same AttributeError when I try to access to the property
              > "c"...
              >[/color]

              Comment

              • Richard Copeland

                #8
                Re: How to customize getattr(obj, prop) function ?

                I tested the exact code I sent you on python 2.4.1. What version of
                Python are you using?

                Thanks,
                Rick

                Pierre wrote:[color=blue]
                > Nop I get the same AttributeError when I try to access to the property
                > "c"...
                >[/color]

                Comment

                • Richard Copeland

                  #9
                  Re: How to customize getattr(obj, prop) function ?

                  I tested the exact code I sent you on python 2.4.1. What version of
                  Python are you using?

                  Thanks,
                  Rick

                  Pierre wrote:[color=blue]
                  > Nop I get the same AttributeError when I try to access to the property
                  > "c"...
                  >[/color]

                  Comment

                  • Pierre

                    #10
                    Re: How to customize getattr(obj, prop) function ?

                    I'm using python 2.4.3.

                    I removed the method __getattribute_ _

                    The mistake was my 3rd underscore :S sorry for wasting your time...

                    The problem is solved ! Thx all !

                    PS: Richard youre message are displayed 3 times ?!

                    Comment

                    • bruno at modulix

                      #11
                      Re: How to customize getattr(obj, prop) function ?

                      Pierre wrote:[color=blue]
                      > Hi,
                      >
                      > Sorry in advance, english is not my main language :/
                      >
                      > I'd like to customize the result obtained by getattr on an object : if
                      > the object has the requested property then return it BUT if the object
                      > doesn't has actually this property return something else.[/color]

                      So implement __getattr__(sel f, name).
                      [color=blue]
                      > In my case, I can't use getattr(object, property, default_value).[/color]

                      Why so ?
                      [color=blue]
                      >
                      > I tried to write a class with a __getattr__ method and even a
                      > __getattribute_ _ method but this doesn't do what I want....[/color]

                      Warning: __getattribute_ _ will take over normal attribute lookup. It can
                      be really tricky. Anyway, you don't need it for your use case - just
                      stick with __getattr__() and you'll be ok.
                      [color=blue]
                      > Maybe I didn't correctly understand this :
                      > http://docs.python.org/ref/attribute-access.html
                      >
                      > Here is a piece of my code :
                      > =============== =============== =======
                      > class myclass:[/color]

                      Make this :
                      class MyClass(object) :

                      [color=blue]
                      > """docstrin g"""
                      >
                      > a = 'aa'
                      > b = 'bb'[/color]

                      a and b are class attributes, not instance attributes. If you want
                      per-instance attributes (which is the most usual case...), you need to
                      define them in a method - usually the __init__() method:

                      def __init__(self):
                      self.a = 'aa'
                      self.b = 'bb'
                      [color=blue]
                      > def __getattr___(se lf, ppt):
                      > """getattr" ""
                      > if hasattr(self, ppt):
                      > return self.ppt[/color]

                      __getattr__() will be called only if the normal attribute lookup fails.
                      So calling hasattr(self, ...) in __getattr__ is useless. More than
                      this: the fact that __getattr__() has benn called means that normal
                      lookup has already failed, so hasattr() will end up calling
                      __getattr__().. .
                      [color=blue]
                      > else:
                      > return "my custom computed result"[/color]





                      (snip)
                      [color=blue]
                      >
                      > if __name__ == "__main__":
                      >
                      > d = myclass()
                      > p1 = getattr(d, "a")[/color]

                      You do understand that getattr(d, "a") is the same as d.a, don't you ?
                      [color=blue]
                      > print p1
                      > p2 = getattr(d, "b")
                      > print p2
                      > p3 = getattr(d, "c")
                      > print p3
                      > =============== =============== ==
                      >
                      > I get an AttributeError when accessing to the property named "c".
                      >
                      > Any explanation/solution to my problem ?[/color]

                      1/ use new-style classes
                      2/ only implement __getattr__()


                      here's a minimal working example:

                      class MyClass(object) :
                      def __init__(self, default='defaul t'):
                      self.a = 'aa'
                      self.b = 'bb'
                      self._default = default

                      def __getattr__(sel f, name):
                      return self._default

                      m = MyClass()
                      m.a
                      m.b
                      m.toto

                      HTH
                      --
                      bruno desthuilliers
                      python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
                      p in 'onurb@xiludom. gro'.split('@')])"

                      Comment

                      • Pierre

                        #12
                        Re: How to customize getattr(obj, prop) function ?

                        I don't want to use getattr(object, property, default_value) because
                        I'm using external code and I don't want to modify or patch it. In this
                        code, the call is getattr(object, property).

                        On my objects, I must provide default values depending on the property
                        that was requested, the default value is not always the same.

                        And Yes I understand that obj.a is equivalent to getattr(obj, 'a') BUT
                        the difference between class attribute and instance attribute... :S

                        Comment

                        • bruno at modulix

                          #13
                          Re: How to customize getattr(obj, prop) function ?

                          Pierre wrote:[color=blue]
                          > I don't want to use getattr(object, property, default_value) because
                          > I'm using external code and I don't want to modify or patch it. In this
                          > code, the call is getattr(object, property).[/color]

                          Seems like a perfectly valid reason !-)
                          [color=blue]
                          > On my objects, I must provide default values depending on the property
                          > that was requested, the default value is not always the same.[/color]

                          On what does it depends ? Attribute name ? Class ? Phase of the moon ?
                          [color=blue]
                          > And Yes I understand that obj.a is equivalent to getattr(obj, 'a') BUT
                          > the difference between class attribute and instance attribute... :S[/color]

                          If you mean you don't understand the difference between a class
                          attribute and an instance attribute, then it would be time to learn
                          Python's OO 101 - else you're in for trouble.

                          For short, an instance attribute has a per-instance value and is
                          (usually) stored in the object's __dict__, while a class attribute is
                          shared by all instances of the class and is (usually) stored in the
                          class's __dict__.


                          class Parrot(object):
                          cls_attr = 'class attribute'

                          def __init__(self):
                          self.instance_a ttr = 'instance attribute'

                          import pprint
                          pprint.pprint(P arrot.__dict__. items())
                          p = Parrot()
                          pprint.pprint(p .__dict__.items ())

                          print Parrot.cls_attr
                          try:
                          print Parrot.instance _attr
                          except AttributeError, e:
                          print e
                          # will lookup 'cls_attr' in p, then in Parrot
                          print p.cls_attr
                          print p.instance_attr

                          # will create an instance attribute 'cls_attr' in
                          # object p, shadowing Parrot.cls_attr
                          p.cls_attr = 'WTF ?'
                          print p.cls_attr
                          print Parrot.cls_attr

                          del p.cls_attr
                          print p.cls_attr
                          print Parrot.cls_attr

                          HTH
                          --
                          bruno desthuilliers
                          python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
                          p in 'onurb@xiludom. gro'.split('@')])"

                          Comment

                          • Ben Finney

                            #14
                            Re: How to customize getattr(obj, prop) function ?

                            [Please provide some context in your reply, so we know what questions
                            or comments you're replying to.]

                            "Pierre" <meyer.p@gmail. com> writes:
                            [color=blue]
                            > I don't want to use getattr(object, property, default_value) because
                            > I'm using external code and I don't want to modify or patch it.[/color]

                            You can subclass the class you want to modify, and override its behaviour.

                            class ScaryExternalTh ing(object):
                            """ The external class we don't want to modify. """

                            class OurModifiedFrie ndlyThing(Scary ExternalThing):
                            """ Class for use by our code. """

                            attr_defaults = {
                            'foo': "eggs",
                            'bar': "beans",
                            }

                            def __getattr__(sel f, name):
                            """ Method invoked when getting an unknown attribute """

                            value = attr_defaults.g et(name, "spam")
                            return value

                            --
                            \ "Welchen Teil von 'Gestalt' verstehen Sie nicht? [What part of |
                            `\ 'gestalt' don't you understand?]" -- Karsten M. Self |
                            _o__) |
                            Ben Finney

                            Comment

                            Working...