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

Python 有没有办法从解释器的内存中删除创建的变量、函数等?,python,memory-management,dir,Python,Memory Management,Dir,几天来,我一直在寻找这个问题的准确答案,但都没有找到好的答案。我不是一个完全的编程初学者,但甚至还没有达到中级水平 当我在Python的shell中时,我键入:dir(),我可以看到当前作用域(主块)中所有对象的所有名称,其中有6个: ['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__'] 然后,当我声明一个变量时,例如x=10,它会自动添加到内置模块dir()下的对象列表中,当我再次键入

几天来,我一直在寻找这个问题的准确答案,但都没有找到好的答案。我不是一个完全的编程初学者,但甚至还没有达到中级水平

当我在Python的shell中时,我键入:
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()

但这一切与我试图实现的目标无关,它不会清除所有使用过的对象。

您可以使用
del
删除单个名称:

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

for name in dir():
    if not name.startswith('_'):
        del globals()[name]
这只是一个循环示例;它防御性地只删除不以下划线开头的名称,从而(不是未搜索的)假设您在解释器中只使用开头不带下划线的名称。如果你真的想彻底了解,你可以使用一个硬编码的名字列表来代替(白名单)。除了退出并重新启动解释器之外,没有内置的函数来为您进行清除


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

实际上,python将回收不再使用的内存。这称为垃圾收集,在python中是一个自动过程。但是,如果您想这样做,您仍然可以通过
delvariable\u name
删除它。您还可以通过将变量分配到
None

a = 10
print a 

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

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

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

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

%reset -f

这应该会起作用。

如果您处于像
Jupyter
ipython
这样的交互式环境中,您可能会对清除不必要的风险值感兴趣,如果它们越来越重

魔法命令
reset
reset\u selective
可在交互式python会话上使用,如
ipython
Jupyter

1)
重置

reset
通过删除用户定义的所有名称(如果在没有参数的情况下调用)来重置命名空间

in
out
参数指定是否要刷新in/out缓存。目录历史记录用
dhist
参数刷新

reset in out
另一个有趣的是只删除numpy数组的
array

reset array
2)选择性重置

通过删除用户定义的名称来重置命名空间。 输入/输出历史记录会保留下来,以备需要

清洁阵列示例:

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']

来源:

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

import gc
gc.collect()
这对我有用

您需要运行两次,一次用于全局,另一次用于本地

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

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

这应该能奏效

globals().clear()

嗯,我不得不说,
startswith(“'')
似乎很幼稚。如果有人足够聪明,可以写
\u foo=42
甚至
\u foo\u\u=42
,我们如何删除这些?有没有办法通过编程方式获取标准模块属性的名称?@georg:我已经对循环进行了防御性编码。如果你想做得更好,你必须硬编码一个名字的初始列表来保存。那么,没办法吗?我的想法是
dir(ModuleType())
,但它只返回
doc
name
@georg:nope;解释器的全局名称空间也因版本而异,并且没有一种简单的方法(据我所知)枚举在稍后阶段打开解释器时所包含的内容。@nakE函数和类与其他任何函数和类一样都是对象。它们并不特别;使用白名单或检查您需要保留的类和函数的对象类型。当然,当在解释器的全局名称空间中工作时,名称不会超出范围,但那又怎样呢我想还值得一提的是,被垃圾收集的对象使用的内存会发生什么情况取决于实现,但在大多数Python实现中,gc的内存只会返回到Python池,在程序退出之前不会返回到操作系统。@PM2Ring LOL:)我想是这样的。python是从哪里来的?请注意,在CPython中,GC仅用于中断引用周期。如果没有剩余的引用,将从内存中删除一个对象。所以,
del
在这里确实有效果。@MartijnPieters,insta被删除了吗?这是一个专业术语吗?:)@埃里克森:是的,按照RFC 4042-bis2的定义,当然-你为什么觉得有必要这么做,还是出于好奇问?我只是不知道那里有一个
del
函数。我要开始了