对象名称前单下划线和双下划线的含义

对象名称前单下划线和双下划线的含义

技术背景

在Python编程中,变量、方法和类的命名规范对于代码的可读性和可维护性至关重要。单下划线和双下划线在对象名称前的使用有特定的含义和约定,了解这些约定有助于编写更加规范和安全的Python代码。

实现步骤

单下划线(_var

  • 类内部使用:在类中,以单下划线开头的属性或方法是一种约定,表明这些属性或方法是供类内部使用的,但Python并不会强制执行这种隐私性。
  • 模块导入限制:在模块中,以单下划线开头的函数通常不应该被其他地方导入。当使用 from M import * 时,如果模块 M 没有定义 __all__ 列表,那么名称以单下划线开头的对象不会被导入。

双下划线(__var

  • 名称修饰(Name Mangling):任何形式为 __spam(至少两个前导下划线,最多一个尾随下划线)的标识符会被文本替换为 _classname__spam,其中 classname 是当前类名,去掉前导下划线。这种修饰机制可以用来定义类私有的实例变量、类变量、方法等,避免子类意外覆盖。

双前导和双尾随下划线(__var__

这是Python用于定义特殊方法的命名约定,例如 __init____len__ 等。这些方法通常由Python系统调用,不建议在自己的代码中使用这种命名方式,以避免与Python的内置方法冲突。

核心代码

单下划线示例

1
2
3
4
5
6
7
8
9
10
# foo.py
var = "var"
_var = "_var"

# bar.py
from foo import *

print(dir()) # 包含 'var' 但不包含 '_var'
print(var) # 输出: var
# print(_var) # 会抛出 NameError

双下划线示例

1
2
3
4
5
6
class MyClass:
__an_attribute = "attribute_value"

my_class = MyClass()
print(my_class._MyClass__an_attribute) # 输出: "attribute_value"
# print(my_class.__an_attribute) # 会抛出 AttributeError

双前导和双尾随下划线示例

1
2
3
name = "test string"
print(name.__len__()) # 输出: 11
print(len(name)) # 输出: 11

最佳实践

  • 使用单下划线:当你希望表明某个属性或方法是供类内部使用,或者模块中的某个函数不应该被外部导入时,使用单下划线。
  • 使用双下划线:当你需要确保某个类的属性或方法不会被子类意外覆盖时,使用双下划线。
  • 避免使用双前导和双尾随下划线:除非你要定义Python的特殊方法,否则避免使用这种命名方式。

常见问题

单下划线真的是“私有”的吗?

不是,单下划线只是一种约定,Python并不会强制执行这种隐私性。其他开发者仍然可以访问以单下划线开头的属性或方法。

双下划线能完全阻止外部访问吗?

不能,双下划线只是通过名称修饰来减少意外访问的可能性,但如果你知道修饰后的名称,仍然可以访问这些属性或方法。

如何正确使用这些命名约定?

根据你的需求和代码的设计意图来选择合适的命名约定。如果只是希望提醒其他开发者某个属性或方法是内部使用的,使用单下划线;如果需要确保子类不会意外覆盖某个属性或方法,使用双下划线。


对象名称前单下划线和双下划线的含义
https://119291.xyz/posts/meanings-of-single-and-double-underscores-before-object-names/
作者
ww
发布于
2025年5月26日
许可协议