python - 删除传递给Python函数的变量引用
问题描述
给定以下代码:
import numpy as np
import psutil
original = np.ones(2**28) / 2
def func1(x):
print(1,psutil.virtual_memory().percent)
x=x**2
print(2,psutil.virtual_memory().percent)
func2(x)
def func2(x):
print(3,psutil.virtual_memory().percent)
y=x**2
print(4,psutil.virtual_memory().percent)
del x # this does not lower the memory usage
print(5,psutil.virtual_memory().percent)
return
func1(original)
是否有可能改变func1
以降低 in 之后的内存del x
消耗func
?(因为传递给func2
的变量不再对 有用func1
)。
例如,以下内容不起作用:
import numpy as np
import psutil
original = np.ones(2**28) / 2
def func1(x):
print(1,psutil.virtual_memory().percent)
x=x**2
print(2,psutil.virtual_memory().percent)
x=[x]
func2(x.pop())
def func2(x):
print(3,psutil.virtual_memory().percent)
y=x**2
print(4,psutil.virtual_memory().percent)
del x # this does not lower the memory usage
print(5,psutil.virtual_memory().percent)
return
func1(x)
注意:假设func2
是无法更改的外部代码。
func1
换句话说,我希望x
在.func2
x
func2
解决方案
在当前的 CPython 实现下,当执行 Python 函数调用时,调用者保留所有参数引用的所有权,直到调用完成。被调用者不是转移所有权,而是获得新的或借用的引用(取决于被调用者的实现方式,尤其是它是用 C 还是 Python 编写的)。
无法将所有权转移给被调用者,被调用者也无法清除调用者的引用。即使您尝试使用类似pop
技巧来确保调用者没有引用参数的变量,调用者的字节码操作数堆栈中仍然有一个引用,并且该引用仅在调用完成后才会被清除。(您可以在 CPython源代码中看到这一点。)
你最好的办法是直接将包装器列表传递给func2
,除非你说你无权访问源代码func2
,所以你不能修改它来获取这样的列表。
你很不走运。
推荐阅读
- laravel - 按数组顺序附加数据透视表 id
- c# - 我的服务堆栈服务中的异常没有将消息移动到死信队列
- encryption - OpenResty lua-resty-string:无法解密由 Crypto-JS 加密的密码(AES 默认)
- java - 如何使用其他 DTO 来减少 Spring Boot 中的 if 语句
- ios - 检查哪个 UIScrollView 正在滚动?
- travis-ci - Travic CI 提交失败(coverage_clover XML 文件不可读)
- teamcity - TeamCity 正在用星号替换特定短语
- cassandra - 使用 Cassandra 表作为键值对的正确做法是什么。并对该表执行批量读写
- javascript - Highcharts 图例显示异常管道
- php - 多个相邻结果对的总和