Bastiaan
Bastiaan

Reputation: 4672

Python function to return property of function construct

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

Answers (1)

dbra
dbra

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

Related Questions