📜  Python中的私有变量

📅  最后修改于: 2020-01-13 11:56:21             🧑  作者: Mango

在Python中,不存在“私有”实例变量,只有在对象内部无法访问。但是,大多数Python代码和编码器都遵循约定,即以下划线作为前缀的名称,例如_芒果应该被视为API或任何Python代码的非公开部分,无论它是函数,方法或数据成员。在进行此操作时,我们还将尝试理解各种形式的尾随下划线的概念,例如,对于range(10)中的_,__ init __(self)。
在Python中,有一种称为名称处理的方法,这意味着对类专用成员的有效用例,提供了有限的支持,基本上是为了避免名称与子类定义的名称发生名称冲突。格式为__芒果的任何标识符(至少两个前导下划线或至多一个尾随下划线)将被_classname__芒果替换,其中classname是当前的类名。只要它在类的定义内发生,就可以完成这种处理。这有助于让子类重写方法而不会中断类内方法调用。
让我们看一下这个例子,尝试找出下划线的工作方式:

# Python代码,展示下划线工作方式
class Map:
    def __init__(self, iterate):
        self.list = []
        self.__芒果(iterate)
    def 芒果(self, iterate):
        for item in iterate:
            self.list.append(item)
    # private拷贝芒果()方法
    __芒果 = 芒果
class MapSubclass(Map):
    # 提供了新的芒果()但没有破坏__init__()
    def 芒果(self, key, value):
        for i in zip(keys, values):
            self.list.append(i)

修改规则主要是为了避免发生意外而设计的,但是仍然可以访问或修改被视为私有的变量。这在特殊情况下(例如在调试器中)甚至很有用。

_单首划线

因此,基本上,方法、函数或数据成员开头的下划线表示您不应该访问此方法,因为它不是API的一部分。让我们看一下这段代码:

# Python代码展示单首划线
def _get_errors(self):
    if self._errors is None:
        self.full_clean()
    return self._errors
errors = property(_get_errors)

该片段摘自Django源代码(django / forms / forms.py)。这表明错误是一个属性,它也是API的一部分,但是_get_errors方法是“私有的”,因此不应访问它。

__双下划线

一开始有两个下划线会引起很多混乱,这涉及语法而不是约定。双下划线将修饰类的属性名称,以避免类之间的属性名称冲突。例如:

# Python代码,展示双下划线
class 芒果:
    def _single_method(self):
        pass
    def __double_method(self): # for mangling
        pass
class Pyth(芒果):
    def __double_method(self): # for mangling
        pass

__双首和双尾划线__

还有另一种情况是双首和双尾划线。在使用特殊变量或方法(称为“魔术方法”)(例如__len __,__ init__)时,我们会遵循此步骤。这些方法为名称提供了特殊的语法功能。例如,__file__表示Python文件的位置,当执行a == b表达式时,将执行__eq__。
例:

# Python代码,展示双首和双尾划线
class 芒果:
    # '__init__' 为了初始化
    def __init__(self, ab):
        self.ab = ab
    # 定制化特别方法,最好别用
    def __custom__(self):
        pass