Tricky Areas in Python

Bengt Richter bokr at oz.net
Tue Oct 25 17:46:35 CEST 2005


On Tue, 25 Oct 2005 10:44:07 +0200, "Fredrik Lundh" <fredrik at pythonware.com> wrote:

>Alex Martelli wrote:
>
>>> my hard-won ignorance, and admit that I don't see the
>>> problem with the property examples:
>>>
>>> >     class Sic:
>>> >         def getFoo(self): ...
>>> >         def setFoo(self): ...
>>> >         foo = property(getFoo, setFoo)
>>
>> Sorry for skipping the 2nd argument to setFoo, that was accidental in my
>> post.  The problem here is: class Sic is "classic" ("legacy",
>> "old-style") so property won't really work for it (the setter will NOT
>> trigger when you assign to s.foo and s is an instance of Sic).
>
>what's slightly confusing is that the getter works, at least until you attempt
>to use the setter:
>
>>>> class Sic:
>...     def getFoo(self):
>...         print "GET"
>...         return "FOO"
>...     def setFoo(self, value):
>...         print "SET", value
>...     foo = property(getFoo, setFoo)
>...
>>>> sic = Sic()
>>>> print sic.foo
>GET
>FOO
>>>> sic.foo = 10
>>>> print sic.foo
>10
>
>(a "setter isn't part of an new-style object hierarchy" exception would have
>been nice, I think...)
>
Hm, wouldn't that mean type(sic).__getattribute__ would have to look for type(sic).foo.__get__
and raise an exception (except for on foo functions that are supposed to be methods ;-)
instead of returning type(sic).foo.__get__(sic, type(sic)) without special casing to reject
non-function foos having __get__? I guess it could. Maybe it should.

BTW, I know you know, but others may not realize you can unshadow foo
back to the previous state:

 >>> sic.foo = 10
 >>> print sic.foo
 10
 >>> del sic.foo
 >>> print sic.foo
 GET
 FOO

and that applies even if __delete__ is defined in the property:

 >>> class Sic:
 ...     def getFoo(self):
 ...         print "GET"
 ...         return "FOO"
 ...     def setFoo(self, value):
 ...         print "SET", value
 ...     def delFoo(self):
 ...         print "DEL"
 ...     foo = property(getFoo, setFoo, delFoo)
 ...
 >>> sic = Sic()
 >>> print sic.foo
 GET
 FOO
 >>> sic.foo = 10
 >>> print sic.foo
 10
 >>> del sic.foo
 >>> print sic.foo
 GET
 FOO

but it won't go beyond the instance for del foo

 >>> del sic.foo
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
 AttributeError: Sic instance has no attribute 'foo'

Regards,
Bengt Richter



More information about the Python-list mailing list