Python self.variable vs private member instance variable



我刚开始用Python编程,有一些与OOP相关的内容我不太清楚。因此,在 Python 中,您可以为新变量创建和赋值,而无需先声明它。因此,为自身创建和分配新变量之间有什么区别(例如。self.variable = 5)在函数内部(例如。__init__()) 与创建和分配新的私有成员变量?在我看来,根本没有区别。

class Foo:
__var_A = 5;
def __init__(self):
self.__var_B = 5;
self.printVars()
def printVars(self):
print(self.__var_A)
print(self.__var_B)

foo = Foo()

事实上,这两个变量之间存在差异:

由于__var_A是在class Foo中定义的,而不是像__init__这样的单个成员函数,因此您可以像这样一次为所有实例更改它:

Foo._Foo__var_A = 2

这不适用于__var_B,因为您为每个实例单独定义它。

但请注意,更改实例上的__var_A不会为其他所有人更改它,而是将本地覆盖放入对象本身:

foo2 = Foo()
foo2._Foo__var_A = 1
Foo._Foo__var_A = 2
(foo2._Foo__var_A, foo._Foo__var_A) # Returns: (1, 2)
在我看来根本没有

区别。

这是正确的。

但请记住,Python 没有"私有"成员。这只是一个惯例。

protectedpublic之间的区别是一个惯例问题。以一个_为前缀的类或成员变量向开发人员指示"除非你知道自己在做什么,否则不要使用它"。但是,私人的情况略有不同:它们需要两个_并且不能以多个_为后缀。以下是文档:

Python中不存在只能从对象内部访问的"私有"实例变量。但是,大多数 Python 代码都遵循一个约定:以下划线(例如 _spam)为前缀的名称应被视为 API 的非公共部分(无论是函数、方法还是数据成员)。它应被视为实施细节,如有更改,恕不另行通知。

名称重整是 Python 继承的重要组成部分。它允许类保护 API 调用免受后代的意外操作(请参阅上面的文档)。但是,如有必要,您仍然可以通过_<class-name><var name>.例如:

class Foo:
def __init__(self):
self.__bar = 1
print(Foo()._Foo__bar)
# 1

如果变量在__init__(self)class foo:下声明,则没有区别。 这两种方法都完成相同的操作。

但是,如果变量(例如self.bar) 是从__init__以外的方法声明的。 用

def bar(self):
self.bar = 'test'

在对象中创建一个不属于默认类的变量。 你可以这样做,但这不是python的良好编程实践。

有区别。请考虑以下示例:

foo = Foo()
foo.__dict__

这将返回:

{'_Foo__var_B': 5}

但是,以下代码:

bar = Foo
bar.__dict__

会回来

{'_Foo__var_A': 5,
'__doc__': None,
'__init__': <function __main__.__init__>,
'__module__': '__main__',
'printVars': <function __main__.printVars>}

由此得出的结论是,即使Foo未实例化,__var_A也可以访问,而__var_B则无法访问。

最新更新