f-string会修改插入值吗?为何两次获取wrapper的ID结果不同?
问题:装饰器返回的ID为何在f-string中表现不同?
先看第一段代码,两次调用装饰器后,变量a和b打印出的ID完全相同:
def my_decorator(func): def wrapper(): pass return id(wrapper) def some_func(): pass a = id(my_decorator(some_func)) b = id(my_decorator(some_func)) print(a) print(b) # 二者返回相同ID
但将wrapper的ID放入f-string后,两次结果的ID却不一样:
a = f"foo - { id(my_decorator(some_func)) }" b = f"foo - { id(my_decorator(some_func))} " print(a) print(b) # 返回不同ID
原因解析
这本质是Python对象垃圾回收时机与内存复用导致的:
第一段代码的逻辑:
每次调用my_decorator(some_func)都会生成全新的wrapper函数对象,但函数执行完毕后,这个wrapper没有被任何变量持有引用,会被Python立刻回收内存。下一次调用my_decorator时,新生成的wrapper会复用之前被回收的内存地址,因此两次返回的id(wrapper)是同一个整数。再对这个整数取id(),结果自然完全相同。f-string场景的逻辑:
构建f-string时,id(my_decorator(some_func))计算出的整数(即wrapper的内存地址)会被临时用于字符串拼接,这个整数对象会被f-string的构建过程短暂持有,不会立刻被回收。这导致第二次调用my_decorator时,新的wrapper无法复用之前的内存地址,只能分配新的内存,因此两次返回的id(wrapper)是不同的整数,最终f-string里显示的ID也就不一样了。
内容的提问来源于stack exchange,提问作者cardinal2000
相关产品推荐
相关产品推荐

