在Python中,对象名称前的单前导下划线和双前导下划线代表什么?
当前回答
_var:python中带前导单下划线的变量是经典变量,旨在通知使用代码的其他人该变量应保留供内部使用。它们与经典变量有一点不同:在对定义它们的对象/模块进行通配符导入时,不会导入它们(定义__all__变量时除外)。如:#foo.pyvar=“var”_var=“_var”#巴.py从foo导入*print(dir())#已定义对象的列表,包含“var”但不包含“_var”打印(var)#varprint(_var)#name错误:未定义名称“_var”_:单下划线是前导单下划线变量的特殊情况。按照惯例,它被用作垃圾变量,以存储一个不打算稍后访问的值。它也不会通过通配符导入来导入。这个for循环打印“我不能在课堂上讲话”10次,并且永远不需要访问_变量。对于范围(10)内的_:打印(“我不能在课堂上讲话”)var_:单尾随下划线变量。它们是传统的变量,用于避免与Python关键字冲突。如:class_=“MyClassName”__var:双前导下划线变量(至少两个前导下划线,最多一个尾随下划线)。当用作类属性(变量和方法)时,这些变量会受到名称篡改:在类之外,python会将属性重命名为_<class_name>__<attribute_name>。例子:类MyClass:__an_attribute=“属性值”my_class=我的类()print(my_class.MyClass__an_attribute)#“属性值”print(my_class.__an_attribute)#AttributeError:“MyClass”对象没有属性“__an_aattribute”当用作类外部的变量时,它们的行为类似于单前导下划线变量。__var__:双前导和尾随下划线变量(至少两个前导和尾随底线)。也称为dunders。python使用此命名约定在内部定义变量。避免使用此约定来防止python更新可能产生的名称冲突。Dunder变量的行为类似于单前导下划线变量:它们在类中使用时不受名称篡改的影响,但不会在通配符导入中导入。
其他回答
单一前导下划线是一种惯例。如果名称是否以单个下划线开头,则从解释器的角度来看没有区别。
双前导和尾随下划线用于内置方法,如__init__、__bool__等。
双前导下划线不带尾随对应符也是一种惯例,但是,类方法将被解释器破坏。对于变量或基本函数名不存在差异。
你的问题很好,不仅仅是关于方法。模块中的函数和对象通常也以一个下划线作为前缀,也可以以两个下划线作为后缀。
例如,__double_underscore名称在模块中不会被篡改。如果从一个模块(从模块导入*)导入所有名称,则不会导入以一个(或多个)下划线开头的名称,也不会导入帮助(模块)中显示的名称。
为了用简单的语言来描述它,让我们将python变量的可访问性约定与Java中的访问修饰符进行比较:
(Python) = (Java)
_single_underscore_variable = Protected (Accessible to class and its subclasses)
__double_underscore_variable = Private (Accessible to class itself only)
no_underscore_variable = Public (Accessible anywhere)
参考:https://www.tutorialsteacher.com/python/public-private-protected-modifiers
了解_和_的事实非常容易;其他答案很好地表达了这一点。这种用法很难确定。
我是这样看的:
_
应用于指示函数不供公共使用,例如API。这和导入限制使其行为与c#中的内部行为非常相似。
__
应用于避免继承层次结构中的名称冲突,并避免后期绑定。很像c#中的private。
==>
如果你想表明某些东西不是供公众使用的,但它应该像受保护的用途一样。如果你想表明某些东西不是公共使用的,但它应该像私人使用一样。
这也是我非常喜欢的一句话:
问题是,一个类的作者可能会合理地认为“属性/方法名称应该是私有的,只能从内部访问这个类定义”,并使用__private约定,该类的用户可以创建合法需要的子类访问该名称。所以要么必须修改超类(这可能很困难或不可能),或者子类代码必须使用手动损坏的名称(这充其量是丑陋和脆弱的)。
但在我看来,如果没有IDE在重写方法时发出警告,那么如果意外地从基类重写了方法,查找错误可能需要一段时间。
如果真的想让变量成为只读的,IMHO最好的方法就是使用property(),只传递getter。有了property()我们可以完全控制数据。
class PrivateVarC(object):
def get_x(self):
pass
def set_x(self, val):
pass
rwvar = property(get_p, set_p)
ronly = property(get_p)
我知道OP问了一个稍有不同的问题,但由于我发现另一个问题是“如何设置私有变量”,标记为与此重复,所以我想在这里添加此附加信息。
推荐文章
- 使用散射数据集生成热图
- python:将脚本工作目录更改为脚本自己的目录
- 如何以编程方式获取python.exe位置?
- 如何跳过循环中的迭代?
- 使用Pandas为字符串列中的每个值添加字符串前缀
- ImportError:没有名为matplotlib.pyplot的模块
- Java中枚举的命名:单数还是复数?
- 在python中遍历对象属性
- 如何在Python中使用方法重载?
- 在Python中提取文件路径(目录)的一部分
- 将类代码分离为头文件和cpp文件
- 如何安装没有根访问权限的python模块?
- 尝试模拟datetime.date.today(),但不工作
- 在PHP中使用getter和setter而不是函数或简单的公共字段有什么优点?
- 将行添加到数组