在python类中,单下划线开头的属性( _attr)和双下划线开头的属性( __attr)主要有以下区别:
1. 命名规范与访问意图
单下划线(_attr):
属于约定俗成的“受保护”属性,仅作为开发者之间的约定,提示该属性不应被外部直接访问,但python本身不强制限制访问。
本质上和普通属性无语法差异,只是一种代码规范(pep 8),用于标识“内部使用”的属性/方法。双下划线(__attr):
属于私有属性,python会对其进行名称改写(name mangling),以防止子类意外覆盖或外部直接访问,是一种语法层面的限制。
2. 名称改写机制
双下划线属性:
python会将__attr自动改写为_类名__attr(例如,类a中的__x会变成_a__x),外部或子类无法直接通过__attr访问,需通过改写后的名称或类内方法访问。
示例:class a: def __init__(self): self.__x = 10 # 双下划线属性 a = a() print(a.__x) # 报错:attributeerror print(a._a__x) # 输出10(可通过改写后的名称访问)单下划线属性:
无名称改写,外部仍可直接访问(如a._x),仅靠开发者自觉遵守“不外部访问”的约定。
示例:class b: def __init__(self): self._y = 20 # 单下划线属性 b = b() print(b._y) # 输出20(无语法限制)
3. 子类继承中的表现
单下划线属性:
子类可直接继承并访问,无语法限制(仍靠约定)。class parent: def __init__(self): self._x = 10 class child(parent): def show(self): print(self._x) # 正常输出10 c = child() c.show()双下划线属性:
子类无法直接访问父类的双下划线属性(因名称改写),需通过父类提供的方法访问。class parent: def __init__(self): self.__x = 10 def get_x(self): return self.__x class child(parent): def show(self): print(self.__x) # 报错:attributeerror(子类自身无__x) print(self.get_x()) # 输出10(通过父类方法访问) c = child() c.show()
4. 用途总结
单下划线(_attr):
用于标识“内部使用”的属性/方法,提醒开发者避免外部直接调用,适用于模块内或类内的私有逻辑,但不强制限制。
常见于模块级别的“私有”函数/变量(如import *不会导入单下划线开头的对象)。双下划线(__attr):
用于真正需要限制访问的场景(如避免子类覆盖父类属性、防止外部篡改),通过名称改写实现语法级别的隔离,但并非绝对安全(仍可通过_类名__attr访问)。
注意
python中不存在真正的“私有”属性,双下划线的限制可被绕过,其设计目的是避免意外冲突,而非阻止恶意访问。实际开发中,单下划线的约定更常用,双下划线慎用(可能增加代码复杂度)。
到此这篇关于python单下划线和双下划线属性区别的文章就介绍到这了,更多相关python单下划线和双下划线区别内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论