Python下划线5种含义代码实例解析

季宁
季宁
发布时间:2026-10-11 | 5人浏览过
原创

本文详细解析Python中下划线的5种核心含义。涵盖单前导下划线的内部使用约定、单末尾下划线的关键字冲突规避、双前导下划线的名称修饰机制、双端双下划线的特殊方法定义,以及独立单下划线在交互环境和解包中的占位作用。通过具体代码实例,帮助开发者规范命名并理解Python的设计哲学。

单前导下划线:内部使用的约定

在Python中,以单个下划线开头的变量或方法名(如 _var)是一种命名约定,用于提示该变量或方法仅供内部使用。这一约定在PEP 8中有所说明,旨在告诉其他开发者,这些成员不应从模块外部直接访问。

需要注意的是,这种约定并不影响Python程序的实际行为。Python不像Java那样有严格的私有和公共访问控制机制,解释器不会阻止外部代码访问以单下划线开头的成员。此外,在使用 dir() 查看对象属性时,以单前导下划线开头的名称会保持原样显示,不会被特殊处理。

单末尾下划线:避免命名冲突

当需要定义的变量名与Python的关键字(如 class、def 等)冲突时,可以使用单末尾下划线(如 var_)来避免语法错误。这是一种在PEP 8中推荐的命名约定。

>>> def make_object(name, class):
SyntaxError: "invalid syntax"

>>> def make_object(name, class_):
...  pass

双前导下划线:名称修饰机制

以双下划线开头的属性名(如 __var)会触发Python的名称修饰(Name Mangling)机制。这一机制主要用于避免子类在重写父类方法时发生命名冲突。

名称修饰的工作原理

当Python解释器遇到以双下划线开头的属性或方法时,会自动将其重命名为 _ClassName__var 的形式。这种修饰对程序员是完全透明的,但会改变 dir() 的输出结果。

class Test:
  def __init__(self):
    self.foo = 11
    self._bar = 23
    self.__baz = 23
>>> t = Test()
>>> 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']

在继承中的作用

名称修饰机制在继承场景中尤为关键。它防止子类意外覆盖父类的双下划线属性或方法。

class ExtendedTest(Test):
  def __init__(self):
    super().__init__()
    self.foo = 'overridden'
    self._bar = 'overridden'
    self.__baz = 'overridden'
>>> t2 = ExtendedTest()
>>> t2.foo
'overridden'
>>> t2._bar
'overridden'
>>> t2.__baz
AttributeError: "'ExtendedTest' object has no attribute '__baz'"

尽管直接访问 t2.__baz 会触发 AttributeError,但通过名称修饰后的属性名 _ExtendedTest__baz 仍然可以访问到覆盖后的值,而父类的 _Test__baz 则保留了原始值。

>>> dir(t2)
['_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']

全局变量与类上下文中的修饰

名称修饰不仅适用于类属性,还适用于类上下文中以双下划线开头的任何名称,包括全局变量。

class ManglingTest:
  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'"

同样,类中的双下划线方法也会受到修饰:

class MangledMethod:
  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

此外,全局变量在类中也会被修饰:

_MangledGlobal__mangled = 23

class MangledGlobal:
  def test(self):
    return __mangled

>>> MangledGlobal().test()
23

双前导和双末尾下划线:特殊方法

以双下划线开头和结尾的名称(如 __var_)不应用名称修饰机制。这类名称通常由Python保留用于特殊用途,例如 __init__(对象构造函数)和 __call__(使对象可调用)等魔术方法(Magic Methods),也被称为dunder方法。

建议开发者避免自定义双前导双末尾下划线的名称,以防与未来Python版本的保留字发生冲突。

class PrefixPostfixTest:
  def __init__(self):
    self.__bam__ = 42

>>> PrefixPostfixTest().__bam__
42

单个独立下划线:占位符与交互环境

单个独立的下划线 _ 通常表示临时或无关紧要的变量。在循环中,如果不需要访问索引,可以使用 _ 作为占位符。在拆分表达式中,它也可以用于忽略特定的值。

>>> car = ('red', 'auto', 12, 3812.4)
>>> color, _, _, mileage = car

>>> color
'red'
>>> mileage
3812.4
>>> _
12

在Python REPL(交互式解释器)中,_ 表示最近一个表达式的结果。利用这一特性,可以方便地访问之前计算的结果。

>>> 20 + 3
23
>>> _
23
>>> print(_)
23

>>> list()
[]
>>> _.append(1)
>>> _.append(2)
>>> _.append(3)
>>> _
[1, 2, 3]

需要注意的是,_ 仅作为有效变量名遵循约定,其具体行为取决于使用场景。

以上就是Python下划线5种含义的详细内容,更多关于Python命名约定和代码规范的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表