因此,我试图找出最好的方法(以最少的代码量实现最优雅的方法)以允许重写python中某个属性的特定功能(例如,仅使用getter,仅使用setter等)。我喜欢下面的属性处理方式,因为它们的所有方法都封装在同一缩进的代码块中(更容易看到处理一个属性的函数在哪里停止,而处理一个属性的函数在哪里停止比较容易下一个开始):
@apply def foo(): """A foobar""" def fget(self): return self._foo def fset(self, val): self._foo = val return property(**locals())
但是,如果我想从以这种方式定义属性的类中继承,然后重写foosetter函数,这似乎很棘手。我做了一些搜索和大多数我已经找到了答案已经在基类来定义不同的功能(例如getFoo和setFoo),明确创建它们(如属性定义foo = property(lambda x: x.getFoo(), lambda x, y: x.setFoo(y), lambda x: x.delFoo())),然后覆盖getFoo,setFoo以及delFoo根据需要。
foo
getFoo
setFoo
foo = property(lambda x: x.getFoo(), lambda x, y: x.setFoo(y), lambda x: x.delFoo())
delFoo
我不喜欢这种解决方案,因为它意味着我必须为每个属性定义lambas,然后写出每个函数调用(在完成之前property(**locals()))。我也没有得到我原来的封装。
property(**locals())
理想情况下,我希望能够执行以下操作:
class A(object): def __init__(self): self.foo = 8 @apply def foo(): """A foobar""" def fget(self): return self._foo def fset(self, val): self._foo = val return property(**locals()) class ATimesTwo(A): @some_decorator def foo(): def fset(self, val): self._foo = val * 2 return something
然后输出将类似于:
>>> a = A() >>> a.foo 8 >>> b = ATimesTwo() >>> b.foo 16
基本上,ATimesTwo继承自getter函数,A但覆盖setter函数。是否有人知道执行此操作的方式(类似于上面的示例)?some_decorator看起来像什么函数,该foo函数应该返回什么?
ATimesTwo
A
some_decorator
我敢肯定,您以前听说过,但自Python 2.3apply起已弃用 八年了 。不要使用它。您对的使用locals()也与Python的Zen背道而驰-显式优于隐式。如果您真的喜欢增加缩进量,则无需创建一次性对象,只需执行
apply
locals()
if True: @property def foo(self): return self._foo @foo.setter def foo(self, val): self._foo = val
不会滥用locals,使用apply,需要创建一个额外的对象,或者之后需要添加一行以foo = foo()使其更难于看到该块的结尾。它对于您的老式使用方式同样有效property-就foo = property(fget, fset)像平常一样。
locals
foo = foo()
property
foo = property(fget, fset)
如果要覆盖任意子类中的属性,则可以使用类似以下的配方。
如果子类知道属性的定义位置,请执行以下操作:
class ATimesTwo(A): @A.foo.setter def foo(self, val): self._foo = val * 2