在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变量的行为类似于单前导下划线变量:它们在类中使用时不受名称篡改的影响,但不会在通配符导入中导入。
其他回答
Python中不存在只能从对象内部访问的“私有”实例变量。然而,大多数Python代码都遵循一个惯例:前缀为下划线的名称(例如_spam)应被视为API的非公共部分(无论是函数、方法还是数据成员)。应将其视为实施细节,如有更改,恕不另行通知。
参考https://docs.python.org/2/tutorial/classes.html#private-变量和类本地引用
单个下划线
在类中,带前导下划线的名称向其他程序员表示该属性或方法将在该类中使用。然而,隐私权并未以任何方式强制执行。对模块中的函数使用前导下划线表示不应从其他地方导入。
从PEP-8风格指南:
_single_leading_underscore:“内部使用”指标较弱。例如,from M import*不会导入名称以下划线开头的对象。
双下划线(名称Mangling)
从Python文档中:
__spam形式的任何标识符(至少两个前导下划线,最多一个尾随下划线)在文本上替换为_classname__spam,其中classname是当前类名,前导下划线被去掉。这种修改是在不考虑标识符的语法位置的情况下完成的,因此它可以用于定义类私有实例和类变量、方法、存储在全局变量中的变量,甚至是存储在实例中的变量。对于其他类的实例,该类是私有的。
以及来自同一页的警告:
名称修改旨在为类提供一种简单的方法来定义“私有”实例变量和方法,而不必担心派生类定义的实例变量,也不必担心类外的代码干扰实例变量。注意,损坏规则的设计主要是为了避免事故;一个坚定的灵魂仍然有可能访问或修改一个被认为是私有的变量。
实例
>>> class MyClass():
... def __init__(self):
... self.__superprivate = "Hello"
... self._semiprivate = ", world!"
...
>>> mc = MyClass()
>>> print mc.__superprivate
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: myClass instance has no attribute '__superprivate'
>>> print mc._semiprivate
, world!
>>> print mc.__dict__
{'_MyClass__superprivate': 'Hello', '_semiprivate': ', world!'}
很好的答案,而且都是正确的。我提供了简单的例子以及简单的定义/含义。
含义:
某些变量--► 这是公开的,任何人都可以看到。
_某些变量--► 这是公开的,任何人都可以看到,但这是一个惯例,表明私人。。。警告Python不执行强制。
__某些变量--► Python将变量名替换为_classname__some_varable(AKA name mangling),并降低/隐藏其可见性,更像是私有变量。
老实说,根据Python文档
无法访问的“Private”实例变量Python中不存在对象“
示例:
class A():
here="abc"
_here="_abc"
__here="__abc"
aObject=A()
print(aObject.here)
print(aObject._here)
# now if we try to print __here then it will fail because it's not public variable
#print(aObject.__here)
如果真的想让变量成为只读的,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问了一个稍有不同的问题,但由于我发现另一个问题是“如何设置私有变量”,标记为与此重复,所以我想在这里添加此附加信息。
单一前导下划线是一种惯例。如果名称是否以单个下划线开头,则从解释器的角度来看没有区别。
双前导和尾随下划线用于内置方法,如__init__、__bool__等。
双前导下划线不带尾随对应符也是一种惯例,但是,类方法将被解释器破坏。对于变量或基本函数名不存在差异。
推荐文章
- 如何排序mongodb与pymongo
- 不可变与可变类型
- 列表是线程安全的吗?
- 操作系统。makdirs在我的路径上不理解“~”
- 如何在Django模板中获得我的网站的域名?
- 在django Forms中定义css类
- 如何在Python中scp ?
- 单元测试的一些常用命名约定是什么?
- Numpy Max vs amax vs maximum
- 我应该在.gitignore文件中添加Django迁移文件吗?
- 每n行有熊猫
- 实例属性attribute_name定义在__init__之外
- 如何获取在Python中捕获的异常的名称?
- 第一次出现的值大于现有值的Numpy
- 如何从Python函数中返回两个值?