在python中使用属性的getter

时间:2018-07-09 11:21:14

标签: python properties getter-setter

我正在研究属性,无法理解getter的用法。

代码:

class A:
    def __init__(self,p):
        self._p = p
    @property
    def p(self):
        return self._p
    @p.setter
    def p(self, value):
        self._p = value
    @p.getter
    def p(self):
        return self._p

所以,我做了以下

obj = A(10)
print(obj.p)

我得到以下输出:

  

10

所以,我认为@ p.getter被调用并返回_q的值。

但是,我尝试如下不使用@ p.getter

class A:
    def __init__(self,p):
        self._p = p
    @property
    def p(self):
        return self._p
    @p.setter
    def p(self, value):
        self._p = value

然后做了

obj = A(10)
print(obj.p)

即使这样,我也得到以下输出:

  

10

所以,我想知道@ p.getter在这里的实际用途是什么,当@property自身能够为我们提供_q的值时

3 个答案:

答案 0 :(得分:4)

如果您想从子类的父类中重写getter,则@property.getter装饰器可能会很有用。它使您可以轻松地“复制”父类中的属性,并仅覆盖getter,同时保持setter和Deleter不变。

示例:

class Parent:
    @property
    def p(self):
        return 'parent'

    @p.setter
    def p(self, value):
        print('setting p to', value)

    @p.deleter
    def p(self):
        print('deleting p')

class Child(Parent):
    @Parent.p.getter
    def p(self):
        return 'child'

print(Parent().p)  # output: parent
print(Child().p)   # output: child
Child().p = 3      # output: setting p to 3
del Child().p      # output: deleting p

答案 1 :(得分:3)

函数上的@property装饰器会创建一个新的property对象,并将装饰后的函数设置为getter。因此,在同一类中,@p.getter装饰器不是很有用,不。

但是,如果您想覆盖子类中的getter或仅重用属性的setter,而完全重用另一个类,则装饰器非常有用:

class Foo(object):
    @property
    def p(self):
        return self._p

    @p.setter
    def p(self, value):
        self._p = value

class Bar(Foo):
    @Foo.p.getter
    def p(self):
        return self._p + 10

或将属性对象复制到另一个类中:

class NotASubclass(object):
    @Foo.p.getter
    def p(self):
        return self._p * 10

现在Bar()NotASubclass的属性p具有不同的getter,但都为Foo()重用了在属性上定义的setter。

在两种情况下,@p.getter装饰器都会创建一个新的property实例来存储为类对象的属性,但是它们的fset属性都指向相同的单个函数对象,充当二传手。这就是在两种情况下仅引用@Foo.p.getter就足够了;您只需要类名称空间中的一个property实例。

另请参见How does the @property decorator work?Python overriding getter without setter

答案 2 :(得分:0)

正如您所注意到的,在这种情况下,因为您已经在此处传递了吸气剂,所以它完全没有用处

@property
def p(self):
    return self._p

,但它至少对于一些极端情况可能有用,例如动态地为现有属性重新定义吸气剂。我不得不说我实际上从未有过这样的用例,但是很好...