当前位置:首页>python>Python 中各种下划线的用法

Python 中各种下划线的用法

  • 2026-09-10 17:15:01
Python 中各种下划线的用法

下划线在 Python 里用途远不止“分隔单词”。一共有六种不同写法,每种都有明确的含义和约定,弄混了要么代码出 bug,要么让同事看不懂你在写什么。

往期阅读>>>

Python 20 个文本分析的库:效率提升 10 倍的秘密武器

Python 金融定价利器FinancePy库深度解析

Python 适合新手的量化分析框架AKQuant解析
Python 25个数据清洗技巧:让你的数据质量提升10倍

Python 为什么会成为AI时代的头部语言

Python 40个常用的列表推导式

Python 50个提高代码开发效率的方法

Python 自动检测服务HTTPS证书过期时间并发送预警

Python 自动化操作Redis的15个实用脚本

Python 自动化管理Jenkins的15个实用脚本,提升效率

Python copyparty搭建轻量的文件服务器的方法

Python 实现2FA认证的方法,提升安全性

Python 封装20个常用API接口,提升开发效率

App2Docker:如何无需编写Dockerfile也可以创建容器镜像

Python 集成 Nacos 配置中心的方法

Python 35个JSON数据处理方法

Python 字典与列表的20个核心技巧

Python 15个文本分析的库,提升效率

Python 15个Pandas技巧,提升数据分析效率

Python 运维中30个常用的库,提升效率

Python调用远程接口的方法

Python 提取HTML文本的方法,提升效率

Python 应用容器化方法:实现“一次部署,处处运行”

Python 自动化识别Nginx配置并导出为excel文件,提升Nginx管理效率

Python 5个常见的异步任务处理框架

Python数据科学常见的30个库

Python 50个实用代码片段,优雅高效


1. 单个下划线(_)

在交互式解释器里,_ 保存着上一次表达式的结果,临时运算很方便:

>>>10+2030>>>_30# _ 保存了上一次的结果>>>_*260

写数字字面量时,_ 可以当千位分隔符用,纯粹是为了可读性,运行时会被忽略:

large_number = 1_000_000print(large_number)  # 输出: 1000000price = 9_999.99print(price)  # 输出: 9999.99

循环里用 _ 表示“这个值我不用”:

# 只跑五次,不需要索引for_inrange(5):print("Hello, Python!")# 解包时丢掉不需要的位置data = (1, 2, 3, 4, 5)first, _, third, _, fifth = dataprint(first, third, fifth)  # 输出: 1 3 5

2. 双下划线开头结尾(__xx__):魔法方法

这是 Python 内置的“特殊方法”专用命名空间,__init__、__str__、__len__ 这些都属于这一类:

classMyClass:def__init__(self, value):self.value = valuedef__str__(self):returnf"MyClass with value: {self.value}"def__len__(self):returnlen(str(self.value))obj = MyClass(42)print(obj)      # 调用 __str__print(len(obj)) # 调用 __len__

不要自己定义 __xxx__ 格式的名字——这个命名空间是 Python 保留的,随版本迭代可能会和新增的内置方法撞名。


3. 单下划线开头(_xx):内部使用

以 _ 开头表示“这是内部实现,外部别直接用”。更实际的效果是:from module import * 不会导入这类名字。

mymodule.py:

defpublic_func():return"This is public"def_internal_func():return"This is internal"

导入行为的差异:

# 方式1:导入整个模块——两个都能用importmymoduleprint(mymodule.public_func())    # 正常print(mymodule._internal_func()) # 技术上可以,但不推荐# 方式2:通配符导入——只导入公共的frommymoduleimport*print(public_func())      # 正常# print(_internal_func()) # NameError:压根没被导入进来

4. 单下划线结尾(xx_):绕过关键词冲突

变量名恰好和关键词撞了,后面加 _ 就能用:

# class = "MyClass"  # SyntaxErrorclass_ = "MyClass"def_ = "function"return_ = "value"print(class_, def_, return_)  # 输出: MyClass function value

不过实际上能用的话,换一个完全不同的名字更好——class_ 读起来总归有点别扭。


5. 双下划线开头(__xx):名称修饰(Name Mangling)

以 __ 开头的属性,Python 会在背后把它改名为 _ClassName__xx,目的是防止子类无意间覆盖父类的属性:

classParent:def__init__(self):self.public = "公共属性"self.__private = "私有属性(经过名称修饰)"defget_private(self):returnself.__privateclassChild(Parent):def__init__(self):super().__init__()self.__private = "子类的私有属性"# 不会覆盖父类的 __privatedefshow_all(self):print(f"公共属性: {self.public}")print(f"尝试访问父类私有属性: {self.get_private()}")print(f"子类自己的私有属性: {self.__private}")parent = Parent()print(parent.public)          # 输出: 公共属性# print(parent.__private)     # AttributeErrorchild = Child()child.show_all()# 公共属性: 公共属性# 尝试访问父类私有属性: 私有属性(经过名称修饰)# 子类自己的私有属性: 子类的私有属性

Parent 里的 __private 实际存储名是 _Parent__private,Child 里的是 _Child__private,两者互不干扰。


6. _ClassName__xx:直接访问被修饰后的名字

既然知道改名规则,就可以绕过去直接访问:

classMyClass:def__init__(self):self.__secret = "隐藏的秘密"obj = MyClass()# print(obj.__secret)         # AttributeErrorprint(obj._MyClass__secret)   # 输出: 隐藏的秘密

这只适合调试或测试场景。正常业务代码里这样写,基本意味着设计出了问题。

综合示例

六种写法放在一个类里看得更清楚:

classExample:def__init__(self):self.normal = "普通属性"self._internal = "内部属性"self.__private = "私有属性"defpublic_method(self):return"公共方法"def_internal_method(self):return"内部方法"def__private_method(self):return"私有方法"defshow_private(self):returnself.__private_method()ex = Example()print(ex.normal)              # 正常print(ex._internal)           # 可以访问,但约定上别这么做print(ex.show_private())      # 通过公共方法访问私有方法# print(ex.__private)         # AttributeError# print(ex.__private_method)  # AttributeError

六种规则里,__xx__ 不要碰(Python 的地盘),_xx 和 __xx 是日常最有用的两种——前者表示“我打算内部用”,后者表示“子类别动”,理解这两个区别就够用了。

“无他,惟手熟尔”!有需要的用起来!
如果你觉得这篇文章有用,欢迎点赞、转发、收藏、留言、推荐❤!

最新文章

随机文章