You could return get, set
(a much more elegant approach) and make your Prop
into
def Prop(fcn):
g, s = fcn()
return property(g, s)
There is however no clean way to not require any return
statement in the decorated function. A function with internal def
statements, just like one with internal assignments, does not actually execute those statements until it gets called -- the objects and names said assignments and def
s are supposed to build and bind are, literally, nowhere to be found.
Once it is called, said names and objects are local to the function -- so, they go away unless external references to them exist... and there's really no more elegant way to ensure such external references to local names exist, besides return
ing them in some form.
The problem comes from insisting that you want to decorate a function object (which keeps its local names very much to itself, by design). Everything would be fine and dandy if you agreed to use the correct keyword instead of def
for the decorated thingy -- that correct keyword is class
. (Note, you need Python 2.6 or better for this purpose)...:
def Prop(cls):
f = cls.__dict__
return property(f['get'], f['set'])
#### test ####
class Example(object):
@Prop
class myattr():
def get(self):
print 'getting', self._value
return self._value
def set(self, value):
print 'setting', value
self._value = value
e = Example()
e.myattr = 'somevalue'
print e.myattr
Classes are much less secretive than functions wrt what's "inside" them, so a class decorator can easily accomplish what you're after. Note the tiny changes: __dict__
to access the dict of the class being decorated, s/def/class/
in the object being decorated, and removal of the return
statement you dislike.