有没有办法从解释器的内存中删除创建的变量,函数等?


113

我一直在寻找这个问题的准确答案已有几天了,但是还没有任何好的结果。我不是编程的完整初学者,但即使在中级水平上也还不是。

当我进入Python的外壳程序时,键入:dir()并且可以看到当前作用域(主块)中所有对象的所有名称,其中有6个:

['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']

然后,例如,当我声明一个变量时,x = 10它会自动添加到内置模块下的对象列表中dir(),当我dir()再次键入时,它现在显示:

['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'x']

函数,类等也是如此。

我如何删除所有这些新对象而不删除开始时可用的标准6?

我在这里已经阅读了有关“内存清理”,“控制台清理”的信息,该命令将删除命令提示符窗口中的所有文本:

>>> import sys
>>> clear = lambda: os.system('cls')
>>> clear()

但是,所有这些都与我要实现的目标无关,它不会清除所有使用过的对象。


2
为什么您觉得需要这样做,还是出于好奇而问?
下午

我只是不知道那里有一个del功能。我开始学习Python,并且经常不得不在shell中进行实验,因此标准变量名(例如x或)y已经经常使用,并且重新启动shell需要花15秒钟的时间(我现在有一台非常老的笔记本电脑)。因此,我想找到一种更快地清理Python内存的方法。
funghorn 2014年

1
啊。FWIW del并非完全是一个函数,因此没有()。这是一个引入del语句的关键字。当然,它实际上如何删除对象可能涉及函数,但这是另一回事了……
PM 2Ring 2014年

试验外壳名称时,除非正在使用,否则不要使用诸如xy不使用的名称。否则,除非您做一些愚蠢的事情,否则您会得到各种各样的垃圾。:)from _somemodule_ import *
PM 2Ring

1
我用谷歌搜索了这个问题,现在我想知道-如果我仍然要删除所有变量和函数,为什么不能重新启动内核并从头开始重新运行脚本?
vagabond

Answers:


159

您可以使用以下方法删除个人名称del

del x

或者您可以将它们从globals()对象中删除:

for name in dir():
    if not name.startswith('_'):
        del globals()[name]

这只是一个示例循环。它只在防御性上删除不以下划线开头的名称,并假设(并非毫无道理)您在解释器的开头仅使用了不带下划线的名称。如果您确实想透彻一点,则可以使用硬编码的名称列表来保留(白名单)。除了退出并重新启动解释器外,没有内置函数可以为您执行清除操作。

您已导入(import os)的模块将保持导入状态,因为它们被sys.modules; 引用。后续导入将重用已经导入的模块对象。您只是在当前的全局名称空间中没有对它们的引用。


好吧,我不得不说startswith('_')似乎很幼稚。如果某人足够聪明_foo=42甚至可以写作__foo__=42,我们如何删除它们?有没有办法以编程方式获取标准模块属性的名称?
乔治2014年

2
@georg:我已经为循环进行了防御性编码。如果您想做得更好,则必须对名称的初始列表进行硬编码。
马丁·彼得斯

所以没办法 我的想法是dir(ModuleType()),但它只会返回docname
乔治2014年

1
@georg:不 解释器的全局名称空间在各个发行版之间也各不相同,并且(我知道)没有万无一失的方法来枚举稍后在您打开解释器时的状态
马丁·彼得斯

1
@nakE函数和类就像其他对象一样。它们并不特殊。使用白名单或检查您需要保留类和函数的对象类型。
马丁·彼得斯

67

是。有一种简单的方法可以删除iPython中的所有内容。在iPython控制台中,只需键入:

%reset

然后系统会要求您确认。按y。如果您不想看到此提示,只需键入:

%reset -f

这应该工作..


1
再一次,为什么这不是最佳答案?
myradio

11
@myradio因为这与不使用IPython的每个人都无关,并且也无法回答问题;该问题询问如何删除全局对象引用,而不是重置IPython shell的内容。
安德烈亚斯(Andreas)

17

您可以使用python垃圾收集器:

import gc
gc.collect()

6
嘿@Fardin!谢谢!您的回答起到了作用,并节省了我的时间!但是在gc.collect()之前,我做了del(variable)。
Gmosy Gnaq '18

9

如果您在的交互式环境中,Jupyter或者,如果您不想要的var变重,则ipython可能需要 清除它们。

magic命令resetreset_selective在交互式python会话(例如ipython和)上可用 Jupyter

1) reset

reset 通过删除用户定义的所有名称(如果不带参数调用)来重置名称空间。

inout参数指定是否要刷新输入/输出缓存。目录历史记录将使用dhist参数刷新。

reset in out

另一个有趣的是array,仅删除了numpy数组:

reset array

2)reset_selective

通过删除用户定义的名称来重置名称空间。输入/输出历史记录保留在您需要的时候。

清洁阵列示例:

In [1]: import numpy as np
In [2]: littleArray = np.array([1,2,3,4,5])
In [3]: who_ls
Out[3]: ['littleArray', 'np']
In [4]: reset_selective -f littleArray
In [5]: who_ls
Out[5]: ['np']

来源:http : //ipython.readthedocs.io/en/stable/interactive/magics.html


6

这对我有用。

您需要对全局变量运行两次,然后对本地变量运行

for name in dir():
    if not name.startswith('_'):
        del globals()[name]

for name in dir():
    if not name.startswith('_'):
        del locals()[name]

4

实际上python会回收不再使用的内存。这被称为垃圾回收,这是python中的自动过程。但是,如果您仍然想这样做,则可以通过删除它del variable_name。您也可以通过将变量分配给None

a = 10
print a 

del a       
print a      ## throws an error here because it's been deleted already.

真正从未引用的Python对象回收内存的唯一方法是通过垃圾回收器。del关键字只是将对象的名称解除绑定,但是仍然需要对该对象进行垃圾回收。您可以强制垃圾收集器使用gc模块运行,但这几乎可以肯定是过早的优化,但是它有其自身的风险。使用del并没有真正的效果,因为这些名称会因为超出范围而被删除。


确实。当然,当在解释器的全局名称空间中工作时,名称不会超出范围,而是那样。:)我想也值得一提的是,已被垃圾回收的对象使用的内存发生了什么取决于实现,但是在大多数Python实现中,gc的内存只是返回到Python池,而没有返回到OS,直到程序退出。
下午14年

@ PM2Ring大声笑:)我是这样认为的。您从哪里参考python?
D编码器

2
请注意,在CPython中,仅需要GC即可中断参考循环。如果没有引用保持,对象从内存斯塔-删除。所以del 确实有真正的效果在这里。
马丁·彼得斯

@MartijnPieters,因斯塔搬走了吗?这是一个专业术语吗?:)
Eryk Sun

2
@eryksun:是的,按照RFC 4042-bis2的定义!:-P
的Martijn Pieters的
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.