Python下划线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命名约定和代码规范的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









