如何调用基类的属性,如果该属性在派生类中被覆盖?如何调用基类的属性,如果该属性在派生类中被覆盖?(H

2019-05-13 14:23发布

我改变了我的一些课程从粗放利用getter和setter的一个更Python使用特性。

但现在我卡住了,因为一些我以前的getter或setter方法会调用基类的相应方法,然后执行别的东西。 但是,如何才能用这个属性来实现的呢? 如何调用父类的属性的getter或setter?

当然,只调用该属性本身给人无限递归。

class Foo(object):

    @property
    def bar(self):
        return 5

    @bar.setter
    def bar(self, a):
        print a

class FooBar(Foo):

    @property
    def bar(self):
        # return the same value
        # as in the base class
        return self.bar # --> recursion!

    @bar.setter
    def bar(self, c):
        # perform the same action
        # as in the base class
        self.bar = c    # --> recursion!
        # then do something else
        print 'something else'

fb = FooBar()
fb.bar = 7

Answer 1:

你可能会认为你可以调用基类的功能,这是由物业称为:

class FooBar(Foo):

    @property
    def bar(self):
        # return the same value
        # as in the base class
        return Foo.bar(self)

虽然这是尝试我觉得最明显的事情- 这是行不通的,因为酒吧是一个属性,而不是调用。

但物业只是一个对象,一个getter方法找到相应的属性:

class FooBar(Foo):

    @property
    def bar(self):
        # return the same value
        # as in the base class
        return Foo.bar.fget(self)


Answer 2:

超级应该做的伎俩:

return super().bar

在Python 2.x中,你需要使用更详细的语法:

return super(FooBar, self).bar


Answer 3:

有使用替代super不需要明确引用基类的名称。

基类:

class A(object):
    def __init__(self):
        self._prop = None

    @property
    def prop(self):
        return self._prop

    @prop.setter
    def prop(self, value):
        self._prop = value

class B(A):
    # we want to extend prop here
    pass

在B中,访问该父类A的属性getter:

正如其他人已经回答了,它是:

super(B, self).prop

或在Python 3:

super().prop

这个方法返回的属性的getter,而不是本身的getter返回的值,但它足以延长吸气。

在B中,访问该父类A的属性setter:

到目前为止,我见过的最好的建议如下:

A.prop.fset(self, value)

我相信这是一个更好的:

super(B, self.__class__).prop.fset(self, value)

在该示例中两个选项都等效但使用超级具有独立于从基类的优点B 。 如果B是从继承C类也扩展属性,你就不必更新B的代码。

延伸的财产B的全码:

class B(A):
    @property
    def prop(self):
        value = super(B, self).prop
        # do something with / modify value here
        return value

    @prop.setter
    def prop(self, value):
        # do something with / modify value here
        super(B, self.__class__).prop.fset(self, value)

有一点需要注意:

除非你的财产没有一个二传手,你必须定义两个调节器和吸气B即使你只改变其中之一的行为。



Answer 4:

尝试

@property
def bar:
    return super(FooBar, self).bar

虽然我不知道是否Python支持调用基类的属性。 一个属性实际上是设置了指定的功能的调用对象,然后在类取代了名。 这很可能意味着,有没有可用的超强功能。

你可以随时切换你的语法虽然使用属性()函数:

class Foo(object):

    def _getbar(self):
        return 5

    def _setbar(self, a):
        print a

    bar = property(_getbar, _setbar)

class FooBar(Foo):

    def _getbar(self):
        # return the same value
        # as in the base class
        return super(FooBar, self)._getbar()

    def bar(self, c):
        super(FooBar, self)._setbar(c)
        print "Something else"

    bar = property(_getbar, _setbar)

fb = FooBar()
fb.bar = 7


Answer 5:

    class Base(object):
      def method(self):
        print "Base method was called"

    class Derived(Base):
      def method(self):
        super(Derived,self).method()
        print "Derived method was called"

    d = Derived()
    d.method()

(即除非我很想念您解释的东西)



文章来源: How to call a property of the base class if this property is being overwritten in the derived class?