Python中数字符号与int的关联机制及子类化int实现访问日志方法
问题解答
一、实现子类化int并在值被访问时打印日志
首先要明确:int是不可变类型,初始化需通过__new__方法;而“值被访问”的场景覆盖直接打印、运算、类型转换等,需要重写对应的特殊方法来触发日志输出。
示例代码如下:
class subInt(int): def __new__(cls, value): return super().__new__(cls, value) # 直接打印或转换为字符串时触发 def __repr__(self): print('accessing') return super().__repr__() def __str__(self): print('accessing') return super().__str__() # 加法运算(包括被其他数加的场景) def __add__(self, other): print('accessing') result = super().__add__(other) return subInt(result) def __radd__(self, other): print('accessing') result = super().__radd__(other) return subInt(result) # 转换为原生int时触发 def __int__(self): print('accessing') return super().__int__()
测试效果:
num = subInt(4) print(num) # 输出accessing,再输出4 print(num + 2) # 输出accessing,再输出6(subInt实例) print(3 + num) # 输出accessing,再输出7(subInt实例) print(int(num)) # 输出accessing,再输出4
如果需要覆盖更多访问场景(比如减法、比较、哈希等),可以继续重写对应的特殊方法(如__sub__、__eq__、__hash__等),具体取决于你对“值被访问”的定义范围。
二、Python3中数字符号4与int实例4的底层关联机制
- 小整数缓存池优化
Python为提升性能,会对**-5到256之间的整数**预先创建实例并缓存。当你写下数字4时,解释器不会重复创建新实例,而是直接从缓存池中取出已存在的对象:
a = 4 b = 4 print(a is b) # 输出True,说明是同一个对象
超出该范围的整数,每次创建会生成新实例(默认CPython行为):
c = 1000 d = 1000 print(c is d) # 输出False
字面量的解析与对象加载
解释器解析源代码时,会先通过词法分析识别4为整数字面量,编译阶段将其转换为LOAD_CONST操作码,运行时直接从常量池或小整数缓存中加载对应的int实例。int的不可变性
int是不可变类型,实例一旦创建就无法修改值。所有对4的运算(如4+1)都会返回新的int实例(这里是5,同样在缓存池内),原实例保持不变。类型与实例的关系
type(4)返回int,说明4是int类的实例。Python中所有数字字面量都是对应内置类型的实例,而内置类型本身也继承自object,属于对象范畴。
内容的提问来源于stack exchange,提问作者DoubleDouble
相关产品推荐
相关产品推荐

