Crossin的编程教室

为什么Python中有的变量前面要加个下划线_?

大家好,欢迎来到 Crossin 的编程教室。

你有没有在别人的Python代码中看到过,有些变量或方法前面多了一个下划线 _,比如下面这个例子:

class User:    def __init__(self, name, age):        self.name = name          # 正常变量        self._age = age           # 这里多了个下划线        self._password = "secret" # 这个也是
    def get_info(self):        return f"Name: {self.name}, Age: {self._age}"
    def _validate_age(self, new_age):  # 方法前面也加了下划线        return new_age > 0

你可能会感到困惑:为什么不直接叫 age 和 validate_age 呢?这么写是有什么特殊的作用吗?

今天 Crossin 就聊一下这个看似不起眼、却非常重要的 Python 命名小细节。

和很多主流语言不一样,Python 没有 private、protected 关键字来强制限制变量或方法的访问权限。这是因为 Python 的设计哲学是“我们都是成年人”,相信程序员会自觉遵守约定。

所以,下划线就成了大家表达“这个东西是内部用的”的一种通用约定。这套约定主要来自官方的 PEP 8 风格指南:单前导下划线 _var 含义:这是一个 “非公开”(non-public) 或 “内部使用” 的变量/方法。意思就是: “这是我这个模块或类的内部实现细节,你作为外部使用者最好别直接去访问或修改它。”

不过要强调的是:这只是约定,不是强制规则。你仍然可以从外部访问 obj._age,在 Python 语法上没有问题,程序也不会报错。

但不推荐这么做,因为模块或代码的作者以后可能会改这个内部实现,导致你的代码无法兼容而出错。

另外在实际使用中,带下划线的变量有两点特殊的效果:

1. 当别人用 from module import * 时,以 _ 开头的名称不会被导入。

2. 很多IDE(VS Code、PyCharm等)会把带 _ 的成员显示成灰色,提醒你“这可能是内部的”。

为什么需要这个约定?

原因其实很简单:它能提高代码的可读性。别人一看就知道哪些是稳定的公开接口,哪些是可能调整的内部逻辑。这在编写模块、团队协作、或开发大型项目时特别重要。

这就好比,客厅与卧室的区别。客厅里的水果饮料你可以自取,但加了 _ 的成员就是放在卧室抽屉里的物品,虽然没有上锁,作为客人也不应该随便乱翻。

除了最常见的单前导下划线,Python 里下划线还有几种其他常见用法,顺便也说一下,避免混淆:

1. 双前导下划线 __var(名称重整 / Name Mangling)

这会触发 Python 的名称修饰机制。Python 会自动把 __var 改成 _ClassName__var,主要目的是防止子类不小心覆盖了父类的同名属性。

它提供了一种“伪私有”的保护,用得相对少,主要在设计类继承时需要严格避免命名冲突的场景。

示例:

class Parent:    def __init__(self):        self.__secret = "父类的秘密"
class Child(Parent):    def __init__(self):        super().__init__()        self.__secret = "子类的秘密"  # 不会覆盖父类的
c = Child()# print(c.__secret)        # 会报错print(c._Parent__secret)   # 可以这样强制访问(一般不这么干)

2. 单末尾下划线var_

用于避免和 Python 内置关键字冲突,比如 class_、max_、list_ 等。

3. 双前后下划线 __var__(魔法方法 / Dunder方法)

这是 Python 的特殊方法,比如 __init__、__str__、__len__ 等。不要自己随便发明这种名字,它是 Python 内部用的。

4. 单独一个下划线 _

在循环或解包时,用来作为满足语法的临时变量,表示“我不关心这个值”:

for _ in range(5):          # 不需要循环变量    print("hello")
a, _, c = (1, 2, 3)         # 忽略中间的值

简单一句话:Python 中的单前导下划线_var 表示“内部使用/非公开”,是编写规范,不是强制的语法。

Python 虽然“宽松”,但遵守命名规范(尤其是PEP 8)可以写出更专业、可读性和可维护性更高的代码,既提高了代码质量,也更适合团队协作开发。

你还遇到过哪些 Python 的小细节?欢迎在留言区分享。

如果本文对你有帮助,欢迎点赞、评论、转发。你们的支持是我更新的动力~


Crossin的新书《码上行动:用ChatGPT学会Python编程》已经上市了。本书以ChatGPT为辅助,系统全面地讲解了如何掌握Python编程,适合Python零基础入门的读者学习。【点此查看详细介绍】
购买后可加入读者交流群,Crossin为你开启陪读模式,解答你在阅读本书时的一切疑问。
Crossin的其他书籍:

添加微信 crossin123 ,加入编程教室共同学习~
Image
感谢转发和点赞的各位~