小编典典

python中的重写属性

python

因此,我试图找出最好的方法(以最少的代码量实现最优雅的方法)以允许重写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函数,这似乎很棘手。我做了一些搜索和大多数我已经找到了答案已经在基类来定义不同的功能(例如getFoosetFoo),明确创建它们(如属性定义foo = property(lambda x: x.getFoo(), lambda x, y: x.setFoo(y), lambda x: x.delFoo())),然后覆盖getFoosetFoo以及delFoo根据需要。

我不喜欢这种解决方案,因为它意味着我必须为每个属性定义lambas,然后写出每个函数调用(在完成之前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函数应该返回什么?


阅读 284

收藏
2020-12-20

共1个答案

小编典典

我敢肯定,您以前听说过,但自Python 2.3apply起已弃用 八年了
。不要使用它。您对的使用locals()也与Python的Zen背道而驰-显式优于隐式。如果您真的喜欢增加缩进量,则无需创建一次性对象,只需执行

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)像平常一样。

如果要覆盖任意子类中的属性,则可以使用类似以下配方

如果子类知道属性的定义位置,请执行以下操作:

class ATimesTwo(A):
    @A.foo.setter
    def foo(self, val):
        self._foo = val * 2
2020-12-20