本文介绍了Python中单下划线和双下划线("dunder")的各种含义和命名约定,名称修饰(name mangling)的工作原理,以及它如何影响你自己的Python类。
-
单前导下划线:_var
-
单末尾下划线:var_
-
双前导下划线:__var
-
双前导和末尾下划线:__var__
-
单下划线:_
1. 单前导下划线 _var
“嘿,这不是真的要成为类的公共接口的一部分。不去管它就好。“
def __init__(self):
self.foo = 11
self._bar = 23
>>> t.foo
11
>>> t._bar
23
return 23
def _internal_func():
return 42
>>> external_func()
23
>>> _internal_func()
NameError: "name '_internal_func' is not defined"
>>> my_module.external_func()
23
>>> my_module._internal_func()
42
单个下划线是一个Python命名约定,表示这个名称是供内部使用的。 它通常不由Python解释器强制执行,仅仅作为一种对程序员的提示。
2. 单末尾下划线 var_
SyntaxError: "invalid syntax">>> def make_object(name, class_):
... pass
3. 双前导下划线 __var
def __init__(self):
self.foo = 11
self._bar = 23
self.__baz = 23
>>> dir(t)
['_Test__baz', '__class__', '__delattr__', '__dict__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
'__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'__weakref__', '_bar', 'foo']
-
self.foo变量在属性列表中显示为未修改为foo。
-
self._bar的行为方式相同 - 它以_bar的形式显示在类上。 就像我之前说过的,在这种情况下,前导下划线仅仅是一个约定。 给程序员一个提示而已。
-
然而,对于self.__baz而言,情况看起来有点不同。 当你在该列表中搜索__baz时,你会看不到有这个名字的变量。
def __init__(self):
super().__init__()
self.foo = 'overridden'
self._bar = 'overridden'
self.__baz = 'overridden'
>>> t2.foo
'overridden'
>>> t2._bar
'overridden'
>>> t2.__baz
AttributeError: "'ExtendedTest' object has no attribute '__baz'"
['_ExtendedTest__baz', '_Test__baz', '__class__', '__delattr__',
'__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__gt__', '__hash__', '__init__', '__le__',
'__lt__', '__module__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__', '__weakref__', '_bar', 'foo', 'get_vars']
'overridden'
42
def __init__(self):
self.__mangled = 'hello' def get_mangled(self):
return self.__mangled
>>> ManglingTest().get_mangled()
'hello'
>>> ManglingTest().__mangled
AttributeError: "'ManglingTest' object has no attribute '__mangled'"
def __method(self):
return 42 def call_it(self):
return self.__method()
>>> MangledMethod().__method()
AttributeError: "'MangledMethod' object has no attribute '__method'"
>>> MangledMethod().call_it()
42
def test(self):
return __mangled
>>> MangledGlobal().test()
23
有很多要吸收的内容吧。老实说,这些例子和解释不是从我脑子里蹦出来的。我作了一些研究和加工才弄出来。我一直使用Python,有很多年了,但是像这样的规则和特殊情况并不总是浮现在脑海里。
有时候程序员最重要的技能是“模式识别”,而且知道在哪里查阅信息。如果您在这一点上感到有点不知所措,请不要担心。慢慢来,试试这篇文章中的一些例子。
让这些概念完全沉浸下来,以便你能够理解名称修饰的总体思路,以及我向您展示的一些其他的行为。如果有一天你和它们不期而遇,你会知道在文档中按什么来查。
4. 双前导和双末尾下划线 _var_
def __init__(self):
self.__bam__ = 42>>> PrefixPostfixTest().__bam__
42
5.单下划线 _
... print('Hello, World.')
>>> color, _, _, mileage = car>>> color
'red'
>>> mileage
3812.4
>>> _
12
23
>>> _
23
>>> print(_)
23
>>> list()
[]
>>> _.append(1)
>>> _.append(2)
>>> _.append(3)
>>> _
[1, 2, 3]
Python下划线命名模式 - 小结
本文为原创文章,版权归知行编程网所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ 如何使用 python pyglet 模块10/25
- ♥ 如何在linux中查看python的安装路径09/04
- ♥ 如何在python中检查变量的类型10/30
- ♥ 如何用 vscode 编写 python 代码09/25
- ♥ python3 os中创建文件夹的方法有哪些?10/24
- ♥ 如何在 Python 中进行字符串比较大小?09/09
内容反馈