Python中的C#样式属性
我想在Python中定义属性,方式类似于C#,可以有嵌套的获取和设置定义。
这是我目前做到的:
#### definition ####
def Prop(fcn):
f = fcn()
return property(f['get'], f['set'])
#### test ####
class Example(object):
@Prop
def myattr():
def get(self):
return self._value
def set(self, value):
self._value = value
return locals() # <- how to get rid of this?
e = Example()
e.myattr = 'somevalue'
print e.myattr
问题是,这样做仍然需要定义为'return locals()'。
有没有办法去掉这个呢?
也许可以用嵌套的装饰器?
1 个回答
2
你可以用 return get, set
这种更优雅的方式来处理你的 Prop
。
def Prop(fcn):
g, s = fcn()
return property(g, s)
不过,想要在被装饰的函数中不使用任何 return 语句是没有什么“干净”的方法的。一个包含内部 def
语句的函数,和一个包含内部赋值的函数一样,实际上在被调用之前并不会执行这些语句——这些赋值和 def
语句所要创建和绑定的对象和名称,字面上是找不到的。
一旦函数被调用,这些名称和对象就变成了函数内部的局部变量——所以,如果没有外部的引用,它们就会消失……而且,确保局部名称有外部引用的优雅方法,除了以某种形式 return
它们之外,真的没有了。
问题在于你坚持想要装饰一个 函数 对象(按设计,它会把局部名称保留得很私密)。如果你同意用正确的关键字来替代 def
,那么一切都会顺利进行——这个正确的关键字是 class
。(注意,你需要 Python 2.6 或更高版本来实现这一点)……:
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
与函数相比,类在“内部”内容上要透明得多,所以一个 class 装饰器可以轻松实现你想要的效果。注意那些小的变化:用 __dict__
来访问被装饰类的字典,在被装饰的对象中将 def
替换为 class
,并去掉你不喜欢的 return
语句。