【发布时间】:2014-06-26 01:26:08
【问题描述】:
假设我有一个类,我想做很多类似的“属性样式”属性。例如:
class Foo(object):
@property
def foo(self):
return self._foo
@foo.setter
def foo(self, val):
self.update()
self._foo = val
@property
def bar(self):
return self._bar
@bar.setter
def bar(self, val):
self.update()
self._bar = val
@property
def baz(self):
return self._baz
@baz.setter
def baz(self, val):
self.update()
self._baz = val
def update(self):
print "Updating..."
显然这里有很多重复,最好把它排除在外。一种方法是创建一个返回属性的函数:
def create_property(var):
def _setter(self, val):
self.update()
setattr(self, '_' + var, val)
def _getter(self):
return getattr(self, '_' + var)
return property(_getter, _setter)
class Foo(object):
foo = create_property("foo")
bar = create_property("bar")
baz = create_property("baz")
def update(self):
print "Updating..."
或者我可以写一个描述符类:
class UpdateOnChange(object):
def __init__(self):
self.data = WeakKeyDictionary()
def __get__(self, instance, owner):
try:
return self.data[instance]
except KeyError:
raise AttributeError("attribute not set")
def __set__(self, instance, value):
instance.update()
self.data[instance] = value
class Foo(object):
foo = UpdateOnChange()
bar = UpdateOnChange()
baz = UpdateOnChange()
def update(self):
print "Updating"
哪个是最好的/最快的/最 Pythonic 的?
【问题讨论】:
-
描述符正是为此而存在的。所以,在我看来,你应该使用描述符。我故意将其斜体以强调这主要是基于意见的。投票搁置,主要基于意见
-
我也推荐装饰器。虽然如果你将它与元类结合起来,你可以自动获取类变量的名称来构造描述符,从而消除对
self.data字典的需要。对于内存和性能开销而言,这会稍微好一些,但可能更重要的是,您永远不必在所指对象死亡的情况下处理关键冲突或奇怪行为。
标签: python properties descriptor