python - Python中嵌套函数的内存地址
问题描述
我一直明白,在 Python 中使用嵌套函数时,声明的内部函数是在封闭函数调用期间创建的,而在封闭函数返回时,本地范围内的所有名称都将被销毁。
例如,从这篇 Real Python 文章中,
[本地范围]是在函数调用时创建的,而不是在函数定义时创建的,因此您将拥有与函数调用一样多的不同本地范围。即使您多次或递归调用同一个函数也是如此。每次调用都会创建一个新的本地范围。
所以每次调用封闭函数都应该为声明的嵌套函数产生一个新的内存地址,对吧?
def normal_function():
def locally_scoped_function():
pass
print(locally_scoped_function)
normal_function() # <function normal_function.<locals>.locally_scoped_function at 0x109867670>
normal_function() # <function normal_function.<locals>.locally_scoped_function at 0x109867670>
normal_function() # <function normal_function.<locals>.locally_scoped_function at 0x109867670>
为什么地址是locally_scoped_function
静态的?由于每次调用都normal_function
应该重新声明和重新创建函数定义,所以不应该将它存储在内存中的不同插槽中吗?我希望打印出来的每一行都有不同的内存地址。
似乎我错过了一些非常明显的东西。我确实尝试在 StackOverflow 上寻找这个,但令人惊讶的是我无法找到关于这个特定问题的答案。
解决方案
正如@Klaus D. 在评论中所建议的那样 - 当函数被垃圾收集时,很可能下一个创建的函数实例将分配在同一地址中。我们通过一个简单的实验证明这一点
def normal_function():
def locally_scoped_function():
pass
print(locally_scoped_function)
return locally_scoped_function
# Run as before
for i in range(3):
normal_function()
# As before, all instances are created at the same address
<function normal_function.<locals>.locally_scoped_function at 0x7f173835f9d8>
<function normal_function.<locals>.locally_scoped_function at 0x7f173835f9d8>
<function normal_function.<locals>.locally_scoped_function at 0x7f173835f9d8>
# Let's save the created instances to avoid garbage collection
collect_to_avoid_gc = []
for i in range(3):
collect_to_avoid_gc.append(
normal_function()
)
# And indeed we'll see different addresses!
<function normal_function.<locals>.locally_scoped_function at 0x7f1737a32158>
<function normal_function.<locals>.locally_scoped_function at 0x7f1737a32378>
<function normal_function.<locals>.locally_scoped_function at 0x7f1737a32510>
推荐阅读
- django-models - Django 水平总和布尔字段
- r - 如何解释来自 cv.kknn(kknn 包)的交叉验证输出
- r - 是否有一个 R 函数可以将其转换为循环以便从列中选择数据?
- python - 在 python haar cascade 中捕获双眼
- linq - 动态排序列在 linq 中不起作用
- python - 顺序文件抓取文本文件 - 一种更智能的方式?
- android - 赋值不是表达式,在这种情况下只允许使用表达式我知道它已经讨论过但没有理解
- scala - Generate companion object for case class with methods (field = method)
- reactjs - 如何在反应中修复“x不是函数”
- python - 如何在 SQLAlchemy 中确定自引用一对多关系的方向