Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > property decorator and inheritance

Reply
Thread Tools

property decorator and inheritance

 
 
Laurent
Guest
Posts: n/a
 
      11-11-2011
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.
 
Reply With Quote
 
 
 
 
alex23
Guest
Posts: n/a
 
      11-11-2011
On Nov 11, 2:03*pm, Laurent <(E-Mail Removed)> 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'
 
Reply With Quote
 
 
 
 
Laurent
Guest
Posts: n/a
 
      11-11-2011
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 ?"
 
Reply With Quote
 
OKB (not okblacke)
Guest
Posts: n/a
 
      11-11-2011
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
 
Reply With Quote
 
Chris Rebert
Guest
Posts: n/a
 
      11-11-2011
On Thu, Nov 10, 2011 at 9:17 PM, Laurent <(E-Mail Removed)> 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
 
Reply With Quote
 
Laurent
Guest
Posts: n/a
 
      11-11-2011
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.
 
Reply With Quote
 
Laurent
Guest
Posts: n/a
 
      11-11-2011
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.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How to make a method into a property without using the @property decorator Phlip Python 2 10-23-2010 05:25 PM
Enhanced property decorator Daniel Python 4 09-02-2008 07:26 AM
Sitemesh : set property from decorated page for decorator Zaza Java 0 07-04-2008 04:19 PM
Removing inheritance (decorator pattern ?) George Sakkis Python 11 06-17-2008 06:50 PM
Why doesnt __getattr__ with decorator dont call __get_method in decorator glomde Python 5 03-29-2007 02:48 PM



Advertisments