python内部函数和id

标签 python function closures variable-assignment

当我尝试使用Python装饰器时,我得到了一个超出我理解的结果,这与内部函数、闭包、赋值有关

我尝试下面的代码,

def myfunc():
    print("myfunc")

def decorator1(func):
    def inner1(*args, **kwargs):
        func(*args, **kwargs)
    print("inner1 id = %d " % id(inner1))
    # print(inner1.cache)
    # return inner1

def decorator2(func):
    def inner2(*args, **kwargs):
        func(*args, **kwargs)
    inner2.cache = {}
    print("inner2 id = %d " % id(inner2))
    print("\t\t\t cache id = %d " % id(inner2.cache))
    return inner2

# Block1 all same
decorator1(myfunc)
decorator1(myfunc)
decorator2(myfunc)
decorator2(myfunc)
decorator1(myfunc)
decorator1(myfunc)
print()

# Block2 deferrent when d2 = ...
decorator1(myfunc)
decorator1(myfunc)
d1 = decorator2(myfunc)
d2 = decorator2(myfunc)
decorator1(myfunc)
decorator1(myfunc)
print()

# Block3 all same
decorator1(myfunc)
decorator1(myfunc)
decorator2(myfunc)
decorator2(myfunc)
decorator1(myfunc)
decorator1(myfunc)
# print()

并获得以下输出

inner1 id = 7696544290000
inner1 id = 7696544290000
inner2 id = 7696544290000
                        cache id = 7696550302496
inner2 id = 7696544290000
                        cache id = 7696547474720
inner1 id = 7696544290000
inner1 id = 7696544290000

inner1 id = 7696544290000
inner1 id = 7696544290000
inner2 id = 7696544290000
                        cache id = 7696550302496
inner2 id = 7696544291152
                        cache id = 7696547501392
inner1 id = 7696544290144
inner1 id = 7696544290144

inner1 id = 7696544290144
inner1 id = 7696544290144
inner2 id = 7696544290144
                        cache id = 7696548415040
inner2 id = 7696544290144
                        cache id = 7696547350000
inner1 id = 7696544290144
inner1 id = 7696544290144

我的问题是

1 why in Block1, two decorator2 call print same id for inner2, but different id for inner2.cache?

2 why in Block2, inner2 id begin to change, where as in Block1 not? (Block2 assign the returned value, Block1 not.)

最佳答案

Python,当您重新分配变量时,由于 CPython 优化,有时会更改其 id,因此,例如:

def f():
  return None 

$> f.a = {}
$> id(f.a)
$> 140511869957216
$> f.a = {}
$> id(f.a)
$> 140511869504400

您可以查看这个问题how to re-assign variable in python without changing id?也许可以帮助你澄清

这个post非常好,我将重点介绍它给出的一些示例。

x = 500
y = 500
id(x)
4338740848
id(y)
4338741040

这里发生了什么?即使将相同的整数值分配给不同的变量名称后,我们也会在这里得到两个不同的 id。这些实际上是我们在这里观察到的 CPython 优化的效果。 CPython 实现为 -5 到 256 之间的所有整数保留一个整数对象数组。因此,当我们创建该范围内的整数时,它们只是向后引用现有对象。您可以引用以下链接了解更多信息。

关于python内部函数和id,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57542031/

相关文章:

python - 如何在 Python 中声明一个长字符串?

python - 使用python解码tcp数据包

python - 结束一天(日期时间)的最优雅方式是什么?

Swift 等待闭包完成

JavaScript 函数默认参数无法正常工作

javascript - 在循环中根据标准在 IIFE 中调用 setTimeout()

rust - 如何从引用结构的方法返回盒装闭包?

python - MLP分类器: "ValueError: Unknown label type"

javascript - 如何从 Node.js 服务器将函数传递给客户端

javascript - 单击矩形数组的 Loop 中的 Listeners -- 关闭