何时在 Python 中使用一两个下划线 [重复]

Posted

技术标签:

【中文标题】何时在 Python 中使用一两个下划线 [重复]【英文标题】:When to use one or two underscore in Python [duplicate] 【发布时间】:2017-06-05 07:46:37 【问题描述】:

好的,我想我已经理解 Python 中一个和两个标题下划线的用法了。

如果我错了,请纠正我,

    在一个下划线的情况下,下划线阻止from X import *语句导入此类变量。

    在两个下划线的情况下,变量的名称前加上它所属的类的名称,以允许更高级别的“私密性”。

我现在的问题是:为什么不只使用两个下划线?在哪些情况下,首选(或需要)一个下划线而不是两个下划线?

【问题讨论】:

呃,因为他们做的事情不同,就像你自己描述的那样? “为什么要使用两个下划线”这个问题可能更有意义,但我不明白你在问什么。 【参考方案1】:

查看文档。

1.单下划线

来自PEP-8:

_single_leading_underscore:弱“内部使用”指标。例如。 from M import * 不导入名称以下划线开头的对象。

2。双下划线:

来自the Python tutorial:

__spam 形式的任何标识符(至少两个前导下划线,最多一个尾随下划线)在文本上替换为 _classname__spam,其中 classname 是当前类名,前导下划线被去除。这种修饰是在不考虑标识符的语法位置的情况下完成的,因此它可以用于定义类私有实例和类变量、方法、存储在全局变量中的变量,甚至是存储在实例中的变量。在其他类的实例上对此类是私有的。 名称修改旨在为类提供一种简单的方法来定义“私有”实例变量和方法,而不必担心派生类定义的实例变量,或通过类外的代码混淆实例变量。请注意,修改规则主要是为了避免事故。一个坚定的灵魂仍然有可能访问或修改一个被认为是私有的变量。

【讨论】:

【参考方案2】:

简答:使用单个前导下划线,除非您有确实令人信服的理由不这样做(即使这样,也要三思而后行)。

长答案:

一个下划线的意思是“这是一个实现细节”(属性、方法、函数等等),它在 Python 中相当于 Java 中的“受保护”。这是您应该为不属于您的类/模块/包公共 API 的名称使用的名称。这只是一个命名约定(大多数情况下 - 星号导入会忽略它们,但是除了在 Python shell 中之外,您不会在其他任何地方进行星号导入吗?)所以它不会阻止任何人访问这个名称,但是他们'如果有任何损坏,请自行恢复(将此视为“如果未密封,则保修无效”之类的提及)。

两个下划线触发名称修改机制。使用它的正当理由很少——实际上我能想到的只有一个(并且已记录在案):保护名称不被意外在复杂框架内部的上下文中覆盖。例如,在整个 django 代码库(主要在 django.utils.functional 包中)中,这种命名方案的实例可能大约有六个或更少。

就我而言,我必须在 15 年多的时间里使用此功能三次,即便如此我仍然不确定我是否真的需要它。

【讨论】:

我理解你的意思,但是对于类中的私有属性,使用双下划线不是更好吗?对我来说,它们提供了更好的方法来将属性设为私有,而不是一个下划线属性。 @AreTor 重要的是清楚地标记什么是公开的,什么不是 - 不要将属性设为“私有”。实际上,经验丰富的 OO 程序员和新手之间的主要区别之一是,第一个将使其大部分成员受到保护,并且很少使其中一个真正私有,因为几乎没有理由阻止子类访问他们自己的属性之一。大多数情况下,如果您的基类需要为一组实现属性(以及使用它们的方法)提供不同的命名空间,那么最好将其委托给另一个对象。 与 Java 的受保护的出色比较...当人们将单个前导 _private 相关联时,我讨厌它。忽略在 Python 中实际上没有什么是 private 的事实。我们在这里谈论类比。单_ 将是Java 的protected,而双__ 将是Java 的private

以上是关于何时在 Python 中使用一两个下划线 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

何时对 Python 子进程模块使用 Shell=True [重复]

python-字符串+变量

Python 私有变量中两个下划线 _ _item 与 一个下划线的区别 _item

01-变量

HTML / CSS需要帮助在两个元素之间创建下划线[重复]

Python:创建后冻结字典键[重复]