property decorator and inheritance

Discussion in 'Python' started by Laurent, Nov 11, 2011.

  1. Laurent

    Laurent Guest

    Hi. I couldn't find a way to overwrite a property declared using a decorator in a parent class. I can only do this if I use the "classic" property() method along with a getter function. Here's an example:

    #!/usr/bin/python3

    class Polite:

    def __init__(self):
    self._greeting = "Hello"

    def get_greeting(self, suffix=", my dear."):
    return self._greeting + suffix
    greeting1 = property(get_greeting)

    @property
    def greeting2(self, suffix=", my dear."):
    return self._greeting + suffix


    class Rude(Polite):

    @property
    def greeting1(self):
    return self.get_greeting(suffix=", stupid.")

    @property
    def greeting2(self):
    return super().greeting2(suffix=", stupid.")


    p = Polite()
    r = Rude()

    print("p.greeting1 =", p.greeting1)
    print("p.greeting2 =", p.greeting2)
    print("r.greeting1 =", r.greeting1)
    print("r.greeting2 =", r.greeting2) # TypeError: 'str' object is not callable



    In this example I can easily overwrite the greeting1 property. But the inherited greeting2 doesn't seem to be a property but a mere string.

    I use a lot of properties decorators for simple properties in a project andI hate mixing them with a couple of "undecorated" properties that have to be overwritten in child classes. I tried using @greeting2.getter decorator and tricks like this but inheritance overwriting failed every time I used decorators.
    Can someone tell me a way to use decorator-declared properties that can beoverwritten in child classes?? That would be nice.
    Laurent, Nov 11, 2011
    #1
    1. Advertising

  2. Laurent

    alex23 Guest

    On Nov 11, 2:03 pm, Laurent <> wrote:
    > Hi. I couldn't find a way to overwrite a property declared using a decorator in a parent class.


    > class Polite:
    >     @property
    >     def greeting2(self, suffix=", my dear."):
    >         return self._greeting + suffix


    Here you set up greeting2 as a property.

    > class Rude(Polite):
    >     @property
    >     def greeting2(self):
    >         return super().greeting2(suffix=", stupid.")


    Here you call Polite.greeting2 as a function.

    > print("r.greeting2 =", r.greeting2) # TypeError: 'str' object is not callable


    And here it's telling you that you're trying to treat a string - the
    output of Polite.greeting2 - as a function.

    The problem isn't that you cannot override greeting2 on Rude, it's
    that you can't treat properties as functions, so you can't pass in a
    new suffix. Instead, break the suffix out as a class attribute, then
    each descendent just needs to override that attribute:

    class Polite(object):
    suffix = ', my dear'

    @property
    def greeting(self):
    return 'Hello' + self.suffix

    class Rude(Polite):
    suffix = ', stupid'
    alex23, Nov 11, 2011
    #2
    1. Advertising

  3. Laurent

    Laurent Guest

    Yes using a separate class variable would transfer the problem to the classlevel. But adding 10 class variables if I have 10 properties would be ugly.. Maybe I should reformulate the subject of this thread to "is there some python magic to pass parameters to decorator-declared properties ?"
    Laurent, Nov 11, 2011
    #3
  4. Laurent wrote:

    > Yes using a separate class variable would transfer the problem to
    > the class level. But adding 10 class variables if I have 10
    > properties would be ugly. Maybe I should reformulate the subject of
    > this thread to "is there some python magic to pass parameters to
    > decorator-declared properties ?"


    You can't have it both ways. If you want

    myObj.greeting2 # No parentheses

    To evaluate to a string (which it will if it's a property as you
    set it up), then it is necessarily true that myObj.greeting2(somearg) is
    going to try to call that string, which isn't going to work. If you
    need to be able to pass in parameters, then you need greeting2 to be a
    real method, not a property, and you need to get the greeting string
    with

    myObj.greeting2() # Parentheses

    All this is as it should be. The whole point of properties is that
    outside functions accessing them don't "know" that a getter function is
    called behind the scenes.

    --
    --OKB (not okblacke)
    Brendan Barnwell
    "Do not follow where the path may lead. Go, instead, where there is
    no path, and leave a trail."
    --author unknown
    OKB (not okblacke), Nov 11, 2011
    #4
  5. Laurent

    Chris Rebert Guest

    On Thu, Nov 10, 2011 at 9:17 PM, Laurent <> wrote:
    > Yes using a separate class variable would transfer the problem to the class level. But adding 10 class variables if I have 10 properties would be ugly. Maybe I should reformulate the subject of this thread to "is there somepython magic to pass parameters to decorator-declared properties ?"


    Apparently, yes:

    >>> class Foo(object):

    .... @property
    .... def bar(self, arg1='baz', arg2='qux'):
    .... return arg1, arg2
    ....
    >>> Foo.bar.fget(Foo(), 'spam', 'eggs')

    ('spam', 'eggs')
    >>>


    Though I do not like this trick at all.

    Cheers,
    Chris
    --
    http://rebertia.com
    Chris Rebert, Nov 11, 2011
    #5
  6. Laurent

    Laurent Guest

    Hey yes it's working that way. But I don't like it very much either. If as OKB said the whole point is that outside functions can't detect a property then I'm going to stick with the non-decorator way. Thanks anyway.
    Laurent, Nov 11, 2011
    #6
  7. Laurent

    Laurent Guest

    Hey yes it's working that way. But I don't like it very much either. If as OKB said the whole point is that outside functions can't detect a property then I'm going to stick with the non-decorator way. Thanks anyway.
    Laurent, Nov 11, 2011
    #7
    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. glomde
    Replies:
    5
    Views:
    513
    glomde
    Mar 29, 2007
  2. George Sakkis

    Removing inheritance (decorator pattern ?)

    George Sakkis, Jun 15, 2008, in forum: Python
    Replies:
    11
    Views:
    524
    George Sakkis
    Jun 17, 2008
  3. Zaza
    Replies:
    0
    Views:
    612
  4. Daniel

    Enhanced property decorator

    Daniel, Aug 26, 2008, in forum: Python
    Replies:
    4
    Views:
    271
    Gabriel Genellina
    Sep 2, 2008
  5. Phlip
    Replies:
    2
    Views:
    276
    Phlip
    Oct 23, 2010
Loading...

Share This Page