5人参与 • 2026-03-18 • Python
很多人从go/java转python的同学会疑惑
为什么python类的默认构造函数是 init? 不是__init 不是init__ 或者_init_ ?
其实是因为python的语法导致的。python 里面没有pubcli private,甚至默认所有的类的属性都是公开的。让我们回想一下 **python 的“访问控制”哲学: “we are all consenting adults.”(我们都是有共识的成年人)。
python 不强制限制你访问任何属性或方法,而是相信开发者知道自己在做什么。
| 特性 | java / c++ | python |
|---|---|---|
public | 显式声明 | 默认就是公开的 |
private | 编译器强制禁止外部访问 | 没有真正的私有,只有约定 |
| 封装性 | 通过访问修饰符强制实现 | 通过命名约定 + 文档 + 信任实现 |
开头/结尾的命名具有不同的语义和用途。它们不是语法强制的访问控制,而是约定(convention)或语言机制(如名称改写、特殊方法)
| 命名形式 | 是否特殊处理 | 用途说明 | 能否外部访问 | 建议 | 外部使用代码示例 |
|---|---|---|---|---|---|
_xxx | ❌ 否 | 内部实现(约定) | ✅ 能 | 用作“受保护”成员 | print(a._xxx) |
__xxx | ✅ 是(改名) | 避免子类命名冲突 | ✅ 能(改名后) | 用于需隔离的内部属性 | print(a._a__xxx) |
_xxx_ | ❌ 否 | 无特殊含义 | ✅ 能 | 避免使用 | print(a._xxx_) |
__xxx__ | ✅ 是 | 魔术方法(语言保留) | ✅ 能 | 只用于标准魔术方法 | print(a.__xxx__()) |
在 python 中,以单下划线 _ 或双下划线 __ 开头/结尾的命名具有不同的语义和用途。它们不是语法强制的访问控制,而是约定(convention)或语言机制(如名称改写、特殊方法)。下面详细解释四种常见形式的区别:
obj._xxx ✅from module import * 导入(模块级别)protected)class myclass:
def __init__(self):
self._internal = 42
obj = myclass()
print(obj._internal) # 完全合法,但“不推荐”直接用
📌 用途:告诉其他开发者:“这是我的私有实现,未来可能变动,请别依赖它。”
myclass 中定义 __private,实际存储为 _myclass__privateobj._myclass__private ✅class parent:
def __init__(self):
self.__secret = "parent"
class child(parent):
def __init__(self):
super().__init__()
self.__secret = "child" # 不会覆盖父类的 __secret!
c = child()
print(c._parent__secret) # 输出: parent
print(c._child__secret) # 输出: child
📌 用途:防止子类“不小心”覆盖父类的内部属性。
__xxx__)class badexample:
def _method_(self): # ❌ 看起来怪怪的,像拼写错误
pass
🚫 pep 8 建议:不要使用 _xxx_ 这种形式,除非你有非常特殊的理由。
class vector:
def __init__(self, x):
self.x = x
def __add__(self, other): # 支持 +
return vector(self.x + other.x)
def __str__(self): # 支持 str() 和 print()
return f"vector({self.x})"
📌 用途:让自定义对象支持
+,len(),print(),with,for等语言特性。
⚠️ 重要:不要创建自己的
__my_custom_method__!这属于 python 保留命名空间。
| 命名形式 | 是否特殊处理 | 用途说明 | 能否外部访问 | 建议 |
|---|---|---|---|---|
_xxx | ❌ 否 | 内部实现(约定) | ✅ 能 | 用作“受保护”成员 |
__xxx | ✅ 是(改名) | 避免子类命名冲突(名称改写) | ✅ 能(改名后) | 用于真正需要隔离的内部属性 |
_xxx_ | ❌ 否 | 无特殊含义 | ✅ 能 | 避免使用 |
__xxx__ | ✅ 是 | 魔术方法(语言保留) | ✅ 能 | 只用于标准魔术方法 |
__double_leading_and_trailing__: 仅用于魔术方法_single_leading_underscore: 表示内部使用__double_leading_underscore: 触发名称改写- 不要使用
_single_trailing_underscore_,除非是为了避免与关键字冲突(如class_)
记住一句话:
“python 给你自由,但也期望你遵守约定。”
下划线不是锁,而是礼貌的提醒。
到此这篇关于python中单下划线_ 、双下划线__的文章就介绍到这了,更多相关 python单下划线_ 、双下划线__内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论