【问题标题】:Can python private variables even be changed without using object._className__attributeName?甚至可以在不使用 object._className__attributeName 的情况下更改 python 私有变量吗?
【发布时间】:2016-03-25 18:32:25
【问题描述】:

考虑以下代码:

class animal:
    def __init__(self, name):
        self.__name = name

class dog(animal):
    def __init__(self, owner, name):
        self.__owner = owner
        super(dog, self).__init__(name)

terrier = dog('A', 'B')
terrier.owner = 'C'
terrier.name = 'D'
print(terrier._dog__owner, terrier._animal__name)
print(terrier.owner, terrier.name)

输出是:

A B
C D

我了解 Python 私有变量仅受约定保护。但所有其他线程都提到 ._className__attributeName 例如。 terrier._dog__owner 作为更改变量值的唯一方法。在这里,我甚至可以使用 terrier.owner 或 terrier.name 来更改它们。

奇怪的是,两者都给出了不同的输出,如上所示。那么 terrier.owner 或 terrier.name 是否从 terrier._dog__name 或 terrier._animal__name 创建不同的实例?这里到底发生了什么?

【问题讨论】:

  • 是的。 Python 中没有私有属性。
  • 是的,terrier.ownerterrier._dog__owner 的名称不同。为什么你会有其他想法?这和terrier.blah = "foo" 没什么区别。你可以创建任何你想要的属性。
  • 谢谢,但您能解释一下为什么要创建两个不同的对象梗实例,它们会提供两组不同的输出吗?
  • @AnanyaChandra:你没有创建两个单独的实例..
  • @AnanyaChandra:你所做的只是添加额外的属性。它们与双下划线属性独立

标签: python class private


【解决方案1】:

双下划线变量确实不是私有 Java 或 C++ 看待隐私的方式。它们不应该被视为类外代码的私有代码。它们用于避免子类之间的名称冲突,这就是使用类名作为前缀的原因。

例如当您有一个类Foo 的内部实现,并且您不希望子类Bar(Foo) 在其实现中意外使用相同的名称时,您可以使用属性__spam,该属性将转换为@987654324 @ 和_Bar__spam,因此不会发生冲突。

您添加的terrier.ownerterrier.name 属性是独立的,与您的类使用的_dog__owner_animal__name 属性无关。使用双下划线变量名不会阻止创建其他属性,包括没有下划线的相同名称。

【讨论】:

  • 来自 Java 我认为 terrier.__owner 是 terrier.owner 的私有版本。它们是独立的,尽管没有任何关系。明白了。
猜你喜欢
  • 2020-07-05
  • 2017-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-17
  • 1970-01-01
相关资源
最近更新 更多