在Python中,对象名称前的单前导下划线和双前导下划线代表什么?
当前回答
单一前导下划线是一种惯例。如果名称是否以单个下划线开头,则从解释器的角度来看没有区别。
双前导和尾随下划线用于内置方法,如__init__、__bool__等。
双前导下划线不带尾随对应符也是一种惯例,但是,类方法将被解释器破坏。对于变量或基本函数名不存在差异。
其他回答
很好的答案,而且都是正确的。我提供了简单的例子以及简单的定义/含义。
含义:
某些变量--► 这是公开的,任何人都可以看到。
_某些变量--► 这是公开的,任何人都可以看到,但这是一个惯例,表明私人。。。警告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)
有时,您会看到一个带有前导下划线的元组,如
def foo(bar):
return _('my_' + bar)
在本例中,发生的情况是,_()是本地化函数的别名,该函数根据语言环境对文本进行操作以将其转换为适当的语言等。例如,Sphinx这样做,您可以在导入中找到
from sphinx.locale import l_, _
在sphinx.locale中,_()被指定为某个本地化函数的别名。
了解_和_的事实非常容易;其他答案很好地表达了这一点。这种用法很难确定。
我是这样看的:
_
应用于指示函数不供公共使用,例如API。这和导入限制使其行为与c#中的内部行为非常相似。
__
应用于避免继承层次结构中的名称冲突,并避免后期绑定。很像c#中的private。
==>
如果你想表明某些东西不是供公众使用的,但它应该像受保护的用途一样。如果你想表明某些东西不是公共使用的,但它应该像私人使用一样。
这也是我非常喜欢的一句话:
问题是,一个类的作者可能会合理地认为“属性/方法名称应该是私有的,只能从内部访问这个类定义”,并使用__private约定,该类的用户可以创建合法需要的子类访问该名称。所以要么必须修改超类(这可能很困难或不可能),或者子类代码必须使用手动损坏的名称(这充其量是丑陋和脆弱的)。
但在我看来,如果没有IDE在重写方法时发出警告,那么如果意外地从基类重写了方法,查找错误可能需要一段时间。
开头有一个下划线:
Python没有真正的私有方法。相反,方法或属性名称开头的一个下划线表示您不应该访问此方法,因为它不是API的一部分。
class BaseForm(StrAndUnicode):
def _get_errors(self):
"Returns an ErrorDict for the data provided for the form"
if self._errors is None:
self.full_clean()
return self._errors
errors = property(_get_errors)
(此代码片段取自django源代码:django/forms/forms.py)。在这段代码中,error是一个公共属性,但此属性调用的方法_get_errors是“私有”的,因此您不应该访问它。
开头有两个下划线:
这会引起很多混乱。它不应用于创建私有方法。应该使用它来避免方法被子类重写或意外访问。让我们看一个例子:
class A(object):
def __test(self):
print "I'm a test method in class A"
def test(self):
self.__test()
a = A()
a.test()
# a.__test() # This fails with an AttributeError
a._A__test() # Works! We can access the mangled name directly!
输出:
$ python test.py
I'm test method in class A
I'm test method in class A
现在创建一个子类B并为__test方法进行定制
class B(A):
def __test(self):
print "I'm test method in class B"
b = B()
b.test()
输出将是。。。。
$ python test.py
I'm test method in class A
正如我们所看到的,B.test()并没有像我们预期的那样调用B.__test()方法。但事实上,这是__的正确行为。名为__test()的两个方法会自动重命名(损坏)为_A__test()和_B__test(。当你创建一个以__开头的方法时,这意味着你不希望任何人能够覆盖它,你只想从它自己的类内部访问它。
开头和结尾有两个下划线:
当我们看到像__this___这样的方法时,不要调用它。这是python要调用的方法,而不是您。让我们来看看:
>>> name = "test string"
>>> name.__len__()
11
>>> len(name)
11
>>> number = 10
>>> number.__add__(40)
50
>>> number + 50
60
总是有一个运算符或本机函数调用这些神奇的方法。有时它只是在特定情况下python调用的钩子。例如,在调用__new__()构建实例后创建对象时调用__init__()。。。
让我们举个例子。。。
class FalseCalculator(object):
def __init__(self, number):
self.number = number
def __add__(self, number):
return self.number - number
def __sub__(self, number):
return self.number + number
number = FalseCalculator(20)
print number + 10 # 10
print number - 20 # 40
有关详细信息,请参阅[PEP-8指南][1]。有关更多神奇的方法,请参阅[本PDF][2]。[1]: https://www.python.org/dev/peps/pep-0008/#method-名称和实例变量[2] http://github.com/RafeKettler/magicmethods/blob/master/magicmethods.pdf
为了用简单的语言来描述它,让我们将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
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 解析日期字符串并更改格式
- 使用try和。Python中的if
- 如何在Python中获得所有直接子目录