如果在派生类中覆盖此属性,如何调用基类的属性?
我正在把我的一些阶级从吸收者和制定者的广泛使用改变为对属性更为pythonic的使用。
但是现在我被卡住了,因为我之前的一些getter或setter会调用基类的相应方法,然后执行其他的操作。 但是,怎样才能完成属性? 如何在父类中调用属性getter或setter?
当然,调用属性本身会给出无限recursion。
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
你可能会认为你可以调用属性调用的基类函数:
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)
超级应该做的伎俩:
return super().bar
在Python 2.x中,您需要使用更详细的语法:
return super(FooBar, self).bar
有一个替代使用super
,不需要明确引用基类的名称。
基础类A:
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本身,但是扩展getter就足够了。
在B中,访问父类A的属性setter:
我目前看到的最好的build议是:
A.prop.fset(self, value)
我相信这个更好:
super(B, self.__class__).prop.fset(self, value)
在这个例子中,两个选项都是等价的,但是使用super的优点是独立于B
的基类。 如果B
从C
类inheritance,同时扩展属性,则不必更新B
的代码。
B扩展A的完整代码属性:
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 return super(B, self.__class__).prop.fset(self, value)
一个警告:
除非你的财产没有一个setter,否则你必须在B
定义setter和getter,即使你只改变其中一个的行为。
尝试
@property def bar: return super(FooBar, self).bar
虽然我不确定python是否支持调用基类属性。 属性实际上是一个可调用的对象,它使用指定的函数进行设置,然后在类中replace该名称。 这很容易意味着没有可用的超级function。
您可以随时将语法切换为使用property()函数:
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
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()
(也就是说,除非我从你的解释中遗漏了一些东西)