如果基类的数据成员被重写为派生类中的属性,如何调用基类的数据成员?
这个问题类似于 另一个,不同之处在于基类中的数据成员不由描述符协议包装。
换句话说,如果我用派生类中的属性覆盖基类的成员,如何访问该成员?
class Base(object):
def __init__(self):
self.foo = 5
class Derived(Base):
def __init__(self):
Base.__init__(self)
@property
def foo(self):
return 1 + self.foo # doesn't work of course!
@foo.setter
def foo(self, f):
self._foo = f
bar = Base()
print bar.foo
foobar = Derived()
print foobar.foo
请注意,我还需要定义一个 setter,否则基类中 self.foo 的分配将不起作用。
总而言之,描述符协议似乎与继承不能很好地交互......
This question is similar to this other one, with the difference that the data member in the base class is not wrapped by the descriptor protocol.
In other words, how can I access a member of the base class if I am overriding its name with a property in the derived class?
class Base(object):
def __init__(self):
self.foo = 5
class Derived(Base):
def __init__(self):
Base.__init__(self)
@property
def foo(self):
return 1 + self.foo # doesn't work of course!
@foo.setter
def foo(self, f):
self._foo = f
bar = Base()
print bar.foo
foobar = Derived()
print foobar.foo
Please note that I also need to define a setter because otherwise the assignment of self.foo in the base class doesn't work.
All in all the descriptor protocol doesn't seem to interact well with inheritance...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果使用委托而不是继承,生活会更简单。 这是Python。 您没有义务从
Base
继承。但是 Base 的其他方法呢? 您可以简单地复制
LooksLikeDerived
中的名称。是的,它并不感觉“干”。 然而,当像您尝试做的那样在新功能中“包装”某些类时,它可以防止很多问题。
Life is simpler if you use delegation instead of inheritance. This is Python. You aren't obligated to inherit from
Base
.But what about other methods of Base? You duplicate the names in
LooksLikeDerived
and simply.Yes, it doesn't feel "DRY". However, it prevents a lot of problems when "wrapping" some class in new functionality like you're trying to do.
在
Base
中定义使得
foo
成为实例的成员(属性),而不是类的成员(属性)。 类Base
不了解foo
,因此无法通过super()
等方式访问它代码>调用。然而,这不是必需的。 当您实例化
并调用基类的 __init__() 方法
时,这不会导致创建/覆盖属性,而是调用
Derived
的 setter ,意味着self._foo = 5
。 因此,如果您放入吸气剂,您几乎就会得到您想要的东西。 如果您需要在
Base
的构造函数中设置self.foo
的值,只需查看_foo
,它是由@foo.setter
。Defining
in
Base
makesfoo
a member (attribute) of the instance, not of the class. The classBase
has no knowledge offoo
, so there is no way to access it by something like asuper()
call.This is not necessary, however. When you instanciate
and the
__init__()
method of the base class callsthis will not result in the creation / overwriting of the attribute, but instead in
Derived
's setter being called, meaningand thus
self._foo = 5
. So if you putin your getter, you pretty much get what you want. If you need the value that
self.foo
is set to inBase
's constructor, just look at_foo
, which was set correctly by the@foo.setter
.一旦您拥有相同名称“foo”的属性,它就会覆盖名称“foo”的访问行为
唯一的出路似乎是你在 dict 中显式设置 'foo'
顺便说一句:我使用 python 2.5 因此必须稍微更改代码
once you have property with same name 'foo' it overrides the behaviour of access of name 'foo'
only way out seems that you explicitly set 'foo' in dict
btw: I use python 2.5 hence had to change code a bit
老实说,这里要注意的是,您正试图围绕一个很糟糕的设计来扭曲您的代码。 属性描述符处理对“foo”属性的请求,并且您希望完全绕过这些请求,这是错误的。 您已经使 Base.init 分配 foobar._foo = 5,因此这正是 getter 需要查找的位置。
基类(对象):
def init(自身):
自我.foo = 5
Honestly, the thing to look at here is that you're trying to twist your code around a design that is simply poor. The property descriptors handle the request for a 'foo' attribute, and you want to bypass these completely, which is just wrong. You're already causing Base.init to assign foobar._foo = 5, so thats exactly where the getter needs to look, too.
class Base(object):
def init(self):
self.foo = 5