【问题标题】:python oop polymorphismpython oop 多态性
【发布时间】:2011-09-15 08:50:27
【问题描述】:

我不明白为什么这个代码:

class A(object):
    def __init__(self):
        self.__value = 1
    def get_value(self):
        return self.__value

class B(A):
    def __init__(self):
        A.__init__( self )
        self.__value = 2

b = B()

print b.get_value()

给 1,但不给 2。感谢您的帮助。

【问题讨论】:

标签: python oop polymorphism


【解决方案1】:

您的问题是双下划线在 python 中是special,并创建了一些隐私(未强制执行,但它破坏了名称,这就是在这里影响您的原因)。您应该重新创建它而不用双下划线命名变量。此外,您应该使用super 而不是显式调用A.__init__

>>> class A(object):
...     def __init__(self):
...             self.value = 1
...     def get_value(self):
...             return self.value
... 
>>> class B(A):
...     def __init__(self):
...             super(B, self).__init__()
...             self.value = 2
... 
>>> b = B()
>>> b.get_value()
2

如果您不想阅读参考文档,请了解更多详情:

如果您阅读了上面关于“特殊”的链接,该段描述了当您使用 __ 时发生的内部名称修改。简短的回答是A.get_value() 返回_A__value,并且在B 中设置self.__value 实际上设置了一个名为_B__value 的成员变量,这意味着A.get_value() 永远不会看到它。

您可以通过确实做一些事情来向自己证明这一点真正 hinky:

>>> class A(object):
...     def get_value(self):
...             return self._B__value
... 
>>> class B(A):
...     def __init__(self):
...             self.__value = 2
... 
>>> b = B()
>>> b.get_value()
2

【讨论】:

  • 你不是说 super(A, self).__init__() 而不是 super(B, self).__init__()?
  • @scr:不。它需要当前的类。
  • 我知道去掉下划线会带来2,但是为什么它会返回1呢??
  • 如果super(B, self).__init__()被省略,b.get_value()仍然返回2。为什么需要super()
【解决方案2】:

self.__value = 1 创建“私有”字段,以这种方式对儿童是不可见的。

对“受保护”字段使用单下划线。

例如self._value = 1

当您创建名称以双下划线开头的字段时,Python 在添加到对象的 __dict__ 之前对其进行一些修改:

>>> class A(object):
...     def __init__(self):
...         self.__value = 1
...     def get_value(self):
...         return self.__value
...
>>> A().__dict__
{'_A__value': 1}

这就是为什么__value 字段在子对象中不可见。

【讨论】:

  • Python 既没有“私有”也没有“保护”;两者都只是约定,编译器会根据其中之一进行操作。
  • @Ignacio 当然,这就是我用引号括起来这些词的原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-16
  • 1970-01-01
  • 1970-01-01
  • 2016-09-08
  • 2017-06-11
  • 2011-06-12
  • 1970-01-01
相关资源
最近更新 更多