Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中删除传递给函数的变量引用_Python_Memory Management - Fatal编程技术网

在Python中删除传递给函数的变量引用

在Python中删除传递给函数的变量引用,python,memory-management,Python,Memory Management,给定以下代码: 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

给定以下代码:

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)
func
中执行
del x
后,是否可以更改
func1
以降低内存消耗?(因为传递给
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
在请求
func2

之前,将
x
传递给
func2
,并删除其对
x
的内部引用。如果你这样做

x=42

现在有两件事-有一个包含值42的“integer”对象,还有一个指向该integer对象的指针“x”

执行删除x操作时,删除的是指针。请记住,该函数中的
x
在任何其他上下文中都不是
x
。integer对象本身通过引擎盖下的引用计数进行管理。如果没有其他变量指向它,那么解释器将在某个时候继续删除它

若要尝试节省内存,请想象func正在从数组中提取一小块并处理它。当它完成时,没有其他东西需要那片,所以把它扔掉,对吗?有两种可能性

  • 您已完成切片,最后一个引用已消失。。。解释器最终将从内存中删除切片对象

  • 您使用的是numpy(看起来是这样),代码的实现方式使它实际上不会生成副本,但允许您在原有的数据结构上进行操作。在这种情况下,切片只是一个指向数据的指针,而不是数据,因此删除它并不会带来太多好处


  • 不管是哪种方式,您可能在这里寻找错误的位置来尝试保存内存。

    在当前的CPython实现下,在执行Python函数调用时,调用方保留所有参数引用的所有权,直到调用完成。被调用方不转移所有权,而是获取新的或借用的引用(取决于被调用方的实现方式,尤其是它是用C还是Python编写的)

    无法将所有权转移给被调用方,被调用方也无法清除调用方的引用。即使尝试类似于
    pop
    的技巧来确保调用方没有引用参数的变量,调用方的字节码操作数堆栈中仍然存在引用,并且该引用只有在调用完成后才会被清除。(您可以在CPython中看到这一点。)

    你最好直接将包装器列表传递给
    func2
    ,除非你说你无权访问
    func2
    的源代码,所以你不能修改它来获取这样的列表


    您的运气太差了。

    func1
    仍然有自己对
    x
    的引用,并将继续这样做,直到
    func2()
    返回。您在
    func2
    中所能做的任何事情都无法删除该引用。使用可适当减小数组的大小。func1中是否实际使用了func2的返回值?@wwi否,它是not@Barmar遗憾的是,我无法访问
    func2
    的源代码,否则,我可以传递封装在列表中的x,并将其从
    func2
    中的列表中删除。