为什么int的子类允许使用__setattr__设置任意名称的属性?
问题核心原因
二者的实例内存结构与底层实现存在差异,和__setattr__本身的继承逻辑无关。
1. 原生int类型的限制
Python中int、str、float这类基础不可变类型均为C语言实现的内置类型,为了极致的内存与运行效率优化,默认不会给单个实例分配__dict__属性(用于存储动态自定义属性的字典结构),也没有预留自定义属性的存储空间。因此直接给原生int实例添加不存在的属性时,会直接抛出AttributeError。
2. 自定义MyInt子类的特性
所有用户自己用Python语法定义的类(哪怕父类是内置类型),只要没有显式声明__slots__来限制允许的属性列表,Python都会默认给每个实例生成__dict__属性,支持动态添加任意自定义属性。
你可以用以下代码验证二者的区别:
class MyInt(int): pass a = MyInt() print(hasattr(a, '__dict__')) # 输出 True a.x = 1 print(a.__dict__) # 输出 {'x': 1} b = 0 print(hasattr(b, '__dict__')) # 输出 False
如果需要让自定义MyInt类和原生int行为一致,禁止动态添加属性,可以显式声明空的__slots__:
class MyInt(int): __slots__ = () # 限制不允许额外自定义属性 a = MyInt() a.x = 1 # 此处同样会抛出 AttributeError,和原生int表现一致
内容的提问来源于stack exchange,提问作者Z Che
相关产品推荐
相关产品推荐

