编程学习网 > 编程语言 > Python > Python面试题:为什么不建议以下划线作为标识符的开头?
2025
10-20

Python面试题:为什么不建议以下划线作为标识符的开头?


有一次我在咖啡馆碰到一个刚入行的小伙子,他正准备面试 Python 后端开发。他跟我说,简历上写了“熟悉 Python 命名规范”,结果面试官直接抛了个问题:为什么 Python 里不建议用下划线开头作为标识符?他当场就愣住了。其实这个问题看似细节,但背后涉及 Python 的语法规则、社区约定,还有一些隐藏的坑。

下划线在 Python 里的“暗语”

我们先说下 Python 里的下划线,表面上就是个普通字符,但在不同的语境下,它的意义完全不同。比如:


这三种写法效果差别非常大。单下划线 _var 通常表示“内部使用”的变量,告诉别人这是私有实现细节,不建议直接用。双下划线 __var 会触发名字改写(name mangling),Python 编译时会偷偷把它改成 _类名__var,避免子类误用。至于 __xxx__,这是 Python 官方保留的魔术方法,比如 __init____str__,如果你随便乱定义一个 __data__,有可能未来版本 Python 就把它用掉了,到时候代码直接冲突。

所以,当你用下划线开头做变量名,看起来没什么问题,但在别人眼里就会产生歧义:你到底是想写私有变量,还是要搞特殊语法?这就是面试官追问的重点。

单下划线的坑

单下划线 _ 除了标识私有变量之外,还有几个特殊用法。比如在交互式环境里,_ 默认存储上一次计算的结果:


有一次我在 Jupyter Notebook 里调试,写了个 _temp = get_data(),结果 _temp 的值根本不是我函数返回的,而是继承了 _ 的特殊行为,调试半天才发现问题。这个就是典型的“踩坑现场”。

双下划线改写的“迷惑”

再说 __var。很多人以为这是“更严格的私有变量”,其实不然。它的作用主要是防止子类无意间覆盖父类的变量。比如:


你看,这里其实存在两个不同的变量:_A__data 和 _B__data。名字改写虽然避免了冲突,但也让调试和阅读变得非常绕。更坑的是,如果你不知道这个规则,直接访问 b.__data,会发现压根不存在这个属性。面试官要的就是你能说出这种“内部机制”。

双下划线包裹的“魔术域”

Python 内置很多魔术方法,都是 __xxx__ 这种形式,比如:

  • __init__:构造函数
  • __call__:对象可调用
  • __getitem__:支持下标访问

这些名字都是 Python 官方保留的。如果你自己乱写:


虽然现在没问题,但万一未来 Python 真的引入了 __update__ 作为标准方法,你的代码就直接和官方冲突了。PEP8(Python 官方编码规范)里明确说过:不要随便用双下划线包裹,除非你在实现内置协议。

面试官想听到的答案

总结一下,面试官问这个问题的时候,期望你能从几个角度回答:

  1. 可读性问题:下划线开头表示私有,滥用会让别人误解。
  2. 潜在冲突__xxx__ 是官方保留,乱用可能和未来版本冲突。
  3. 特殊语义_ 在 REPL 里有特殊意义,容易踩坑。
  4. 名字改写:双下划线触发 name mangling,调试不便。

能把这几点说清楚,基本就是满分回答了。

实际代码示例

最后我给你们写个完整的小例子,方便记忆:


你会发现 _token 还是能访问,说明单下划线只是约定俗成。而 __password 被改成 _User__password,这就是 name mangling 的效果。至于 __id__,虽然现在没问题,但它可能会和未来的 Python 特性冲突。

写在最后

我个人建议是:能不用下划线开头就别用。如果确实需要表达“内部变量”,用一个 _ 就够了,不要动不动搞双下划线。__xxx__ 这种形式,更是坚决避免,除非你真的在实现 Python 的魔术方法。

这类问题,面试官其实不是为了考你死记硬背,而是想看你对语言细节是否有理解,能不能避免在实际开发中掉坑里。等哪天你在大项目里维护别人写的代码,遇到一堆 __data___temp,你就会明白这个问题的重要性了。

以上就是“Python面试题:为什么不建议以下划线作为标识符的开头?的详细内容,想要了解更多Python教程欢迎持续关注编程学习网。

扫码二维码 获取免费视频学习资料

Python编程学习

查 看2022高级编程视频教程免费获取