Reputation: 4672
Found this construct in the source of some python package (and it's probably more common). What is done with this?
def fie(x):
def foo(y):
return 123
return property(foo)
When trying on a scratchpad I can't do anything with the outcome:
fie(3)
<property object at 0x04D1BDE0>
fie(3)(4)
'property' object is not callable
Upvotes: 1
Views: 1097
Reputation: 631
The function "fie" creates a data descriptor having only a getter, which returns always "123" on every instance "y" is used.
The parameter "y" needed by the protocol even if we bring back a constant, while "x" in the example is not used and confusing, so let we change it a bit:
def fie(x):
def foo(y):
print "Returning x"
return x
return property(foo)
class Dog(object):
age = fie(3)
>>> Dog.age
<property object at 0x1050565d0>
>>> pluto = Dog()
>>> pluto.age
Returning x
3
>>> pluto.age = 5
Traceback (most recent call last):
File "<pyshell#239>", line 1, in <module>
pluto.age = 5
AttributeError: can't set attribute
As you can see, with our new fie function we create an attribute named age with the constant value of 3 on the class Dog. When invoked on the class we still see it as the property's protocol wrapper, but on instance pluto it happens the magic. And because we defined only the getter, the property is read-only.
Note that the class must be of the new-style (i.e. inheriting from object), otherwise the assignment would work and overwrite forever the wrapper, changing the attribute age into an actual integer value within the instance's dictionary:
class Dog2:
age = fie(7)
>>> ploto = Dog2()
>>> ploto.age
Returning original x
7
>>> ploto.age = 8
>>> ploto.age
8
Upvotes: 1