如何在Python脚本的中间清除所有的变量?

107 人关注

我正在寻找类似于Matlab中 "清除 "的东西。一个命令/函数,它可以从工作区移除所有的变量,将它们从系统内存中释放出来。Python中是否有这样的东西?

编辑:我想写一个脚本,在某些时候清除所有的变量。

5 个评论
如果你把标题改为 "如何在Python脚本中间清除所有的变量?",对以后搜索这个主题会有帮助,因为 "如何在Python中重启命令窗口?"与你实际问的问题没有关系。
你能提供任何可能的背景,使之有意义吗?
听起来像是另一个试图将编码习惯从他们的原生环境转移到他们没有任何意义的环境中的案例。
如果你只是担心一些庞大的对象(图像或其他巨大的数组),你可以在完成后 del 它们。 如果你只是担心命名空间会很杂乱,你也许应该重新考虑你的设计,使用这么多的名字。 例如,对于一系列的图像转换,保留每一个中间步骤可能是不必要的。
@S.Lott:控制台中的探索性科学分析。最后出现许多不想要的变量是很常见的(在尝试了一些东西后,又决定那不是一个相关的途径)。但在这种情况下。 约翰-拉鲁瓦的回答 是最合适的。
python
snakile
snakile
发布于 2010-08-23
11 个回答
Alex Martelli
Alex Martelli
发布于 2022-07-15
已采纳
0 人赞同

下面的命令序列确实可以删除 every 命名来自当前模块。

>>> import sys
>>> sys.modules[__name__].__dict__.clear()

我怀疑你是否真的想这样做,因为 "每个名字 "都包括所有的内建程序,所以在这样一个完全被抹去的过程中,你能做的并不多。 记住,在 Python 中真的没有 "变量 "这样的东西 -- 有的是objects有很多种类(包括模块、函数、类、数字、字符串......),而且有名称绑定到对象上;该序列所做的是将每个名字从一个模块中删除(相应的对象会消失,当且仅当对它们的每个引用都被删除)。

也许你想更有选择性,但很难猜到你到底是什么意思,除非你想说得更具体。 但是,只是举一个例子。

>>> import sys
>>> this = sys.modules[__name__]
>>> for n in dir():
...   if n[0]!='_': delattr(this, n)

This sequence leaves alone 名称 that are private or magical, including the __builtins__ special name which houses all built-in 名称. So, built-ins still work -- for example:

>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'n']

正如你所看到的,名字n(在那个for中的控制变量)也恰好被保留下来(因为它每次都被重新绑定在for子句中)。所以把这个控制变量命名为_可能更好。例如,为了清楚地表明 "它是特殊的"(另外,在交互式解释器中,每当在提示符下输入完整的表达式后,名字_都会被重新绑定到该表达式的值上,所以它不会停留很长时间。-).

总之,一旦你确定了它到底是什么is如果你想这样做,不难为之定义一个函数,并把它放在你的启动文件(如果你只想在交互式会话中这样做)或网站定制文件(如果你想在每个脚本中这样做)。

你可以在启动时保留一份原始字典的副本,然后删除已经添加的名字;)然而我认为这显然是对动态系统的滥用,我想不出在什么情况下这样做是没有意义的。
哈哈,这真是太棒了...令人惊讶的是,你这样做会失去多少功能,而你又可以通过做诸如 int = (2).__class__ str = ''.__class__ True = (1 == 1) 等事情来恢复多少功能...
@monoceres,你将如何命名该副本,以及你将把它藏在哪里,以免它也被抹去?)
我越是使用Python,就越是喜欢它。它不仅是一种伟大的语言,你还可以花几个小时简单地摆弄它,让它做一些你真的不应该做的事情;-)
也许我理解错了,但我面临一个问题:当你在某个时刻使用 for n in dir(): ... if n[0]!='_': delattr(this, n) 时, n=this 被你在循环中删除了!所以在下一个迭代中,你在尝试 delattr(this,n) 时遇到了错误,因为你刚刚删除了它。所以在下一个迭代中,你在尝试 delattr(this,n) 时出现了错误,因为你刚刚删除了它!:)所以它不能正确工作
John La Rooy
John La Rooy
发布于 2022-07-15
0 人赞同

不,你最好重新启动解释器

IPython 是捆绑式解释器的一个很好的替代品,并且有 %reset 命令,通常可以工作。

你说的 "不 "是指我不应该做,还是说不可能?如果你说我不应该这样做,你能解释一下原因吗?
+1: It takes less than a quarter of a second for me to ctrl-d then pyt -> tab to get back into the interpreter. No reason to do anything fancy here.
%reset对大多数变量有效,对某些变量则无效。对我来说,只有重启解释器才能保证清理一切。
使用 %reset -f 表示非交互式。 stackoverflow.com/questions/38798181/...
Jochen Ritzel
Jochen Ritzel
发布于 2022-07-15
0 人赞同

如果你写了一个函数,那么一旦你离开它,里面的所有名字都会消失。

这个概念被称为 名称空间 它是如此之好,以至于它被纳入了《世界日报》。 蟒蛇之禅 :

命名空间是一个了不起的想法 -- 让我们做更多这样的事情吧!

The 名称空间 of IPython can likewise be reset with the magic command %reset -f . (The -f means "force"; in other words, "don't ask me if I really want to delete all the variables, just do it.")

David
我再补充一点:如果你把所有的东西都放在一个主函数里面(包括导入),你实际上得到了一个工作场所,你可以通过退出该函数来重置。我相信这的确是问题的目的所在。
Anurag Gupta
Anurag Gupta
发布于 2022-07-15
0 人赞同
from IPython import get_ipython;   
get_ipython().magic('reset -sf')
    
请看一下 如何回答
or simply %reset -sf
实际上,当你用Anaconda提示符运行你的Python脚本时,%reset -sf命令不起作用,并出现错误(即使你使用了try- except;它也不起作用)。你也可以试试,你会发现。但是,在所有可能的情况下,使用ipython库可以解决这个问题。
Jug
Jug
发布于 2022-07-15
0 人赞同

这是亚历克斯的答案的修改版。 我们可以保存一个模块的命名空间的状态,并通过以下2种方法恢复它...

__saved_context__ = {}
def saveContext():
    import sys
    __saved_context__.update(sys.modules[__name__].__dict__)
def restoreContext():
    import sys
    names = sys.modules[__name__].__dict__.keys()
    for n in names:
        if n not in __saved_context__:
            del sys.modules[__name__].__dict__[n]
saveContext()
hello = 'hi there'
print hello             # prints "hi there" on stdout
restoreContext()
print hello             # throws an exception

你也可以在调用saveContext()之前添加一行 "clear = restoreContext",clear()将像matlab的clear一样工作。

很好的回答! 我相信对于 Python 3 来说,你要用 names = list(sys.modules[__name__].__dict__.keys()) 来调整 restoreContext,否则 Python 会抱怨你在遍历它的 dict_keys 对象时改变了字典的大小。
另外,对于那些想要 import 这个答案的人(即我保存了这个,我从Jupyter笔记本中导入这个,以清除家庭作业中不同问题之间的命名空间),我想你会想要使用 "__main__" 而不是 __name__
好的答案。它完全符合我的用例,我通过 reticulate 包中的 source_python 函数从R中调用Python脚本,并且需要确保所有的Python脚本都在一个默认环境中执行,以避免变量和函数定义从一个Python脚本泄漏到另一个脚本中。
tardis
tardis
发布于 2022-07-15
0 人赞同

在Spyder中,人们可以为每个Python文件配置IPython控制台,在每次执行前在菜单中清除所有的变量 Run -> Configuration -> General settings -> Remove all variables before execution

In version 5.05 this is under Tools/Preferences/Run.
Kolay.Ne
Kolay.Ne
发布于 2022-07-15
0 人赞同

注意:你很可能实际上并不想要这个。

替换代码0】函数返回一个字典,其中键是你可以命名的对象的名称(而值,顺便说一下,是这些对象的 id )。 替换代码2】函数接收一个字符串,并执行它,就像你在Python控制台中输入它一样。所以,代码是

for i in globals().keys():
    if not i.startswith('_'):
        exec('del ' + i)

这将删除所有名称不以下划线开头的对象,包括函数、类、导入的库等。

虽然这个代码片断可能会解决这个问题。 包括解释 有助于提高你的回答的质量。记住,你是在为未来的读者回答问题,而那些人可能不知道你的代码建议的原因。
谢谢你。现在好些了吗?
Harold Henson
Harold Henson
发布于 2022-07-15
0 人赞同

在闲置的IDE中,有Shell/Restart Shell。 Cntrl-F6就可以做到这一点。

Ivan
Ivan
发布于 2022-07-15
0 人赞同

最简单的方法不就是创建一个包含所有需要的变量的类吗? 然后你就有一个包含所有当前变量的对象,如果你需要,你可以覆盖这个变量?

Maher Hussein
Maher Hussein
发布于 2022-07-15
0 人赞同

删除一个变量的一个非常简单的方法是使用 del 函数。

a = 30
print(a) #this would print "30"
del(a) #this deletes the variable
print(a) #now, if you try to print 'a', you will get
         #an error saying 'a' is not defined
    
David Weisser
David Weisser
发布于 2022-07-15
0 人赞同