Using 'apply' as a decorator, to define constants

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Sat Aug 22 06:45:13 EDT 2009


On Sat, 22 Aug 2009 10:51:27 +0100, Jonathan Fine wrote:

> Steven D'Aprano wrote:
> 
>> There's a standard idiom for that, using the property() built-in, for
>> Python 2.6 or better.
>> 
>> Here's an example including a getter, setter, deleter and doc string,
>> with no namespace pollution, imports, or helper functions or deprecated
>> built-ins:
>> 
>> class ColourThing(object):
>>     @property
>>     def rgb(self):
>>         """Get and set the (red, green, blue) colours.""" return
>>         (self.r, self.g, self.b)
>>     @rgb.setter
>>     def rgb(self, rgb):
>>         self.r, self.g, self.b = rgb
>>     @rgb.deleter
>>     def rgb(self):
>>         del self.r, self.g, self.b
> 
> 
> Sorry, Steve, but I don't understand this.  In fact, I don't even see
> how it can be made to work.

Nevertheless, it does work, and it's not even magic. It's described (very 
briefly) in the docstring for property: help(property) will show it to 
you. More detail is here:

http://docs.python.org/library/functions.html#property

As for how it can work, it's not that difficult. All you need is for the 
setter and deleter methods to add an appropriate fset and fdel method to 
the property, then return it. Here's a toy example which may demonstrate 
the process (although unlike property, fget, fset and fdel don't have any 
special meanings):

class ToyProperty(object):
    def __init__(self, fget, fset=None, fdel=None, fdoc=None):
        if fdoc is None:
            fdoc = fget.__doc__
        self.fget = fget
        self.fset = fset
        self.fdel = fdel
    def getter(self, fget):
        self.fget = fget
        return self
    def setter(self, fset):
        self.fset = fset
        return self
    def deleter(self, fdel):
        self.fdel = fdel
        return self


> Unless an exception is raised,
>      @wibble
>      def wobble():
>          pass
> will make an assignment to wobble, namely the return value of wibble. So
> in your example above, there will be /three/ assignments to rgb.

Yes. A tiny inefficiency, which only occurs when the class is created. If 
you care about that, then (1) use the full form of property() where you 
supply the fget, fset and fdel arguments all at once, and (2) you really 
need to get out into the fresh air more *wink*



> Unless
> you do some complicated introspection (and perhaps not even then) surely
> they will clobber each other.

So what? The process is no weirder than:

x = ['fget']
x = x + ['fset']
x = x + ['fdel']



-- 
Steven



More information about the Python-list mailing list