【问题标题】:How do I clear all variables in the middle of a Python script?如何清除 Python 脚本中间的所有变量?
【发布时间】:2011-04-02 09:52:36
【问题描述】:

我在 Matlab 中寻找类似于“清除”的东西:一个命令/函数,它从工作区中删除所有变量,从系统内存中释放它们。 Python中有这样的东西吗?

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

【问题讨论】:

  • 如果您将标题更改为“如何清除 Python 脚本中间的所有变量?”之类的内容会很有帮助。用于该主题的未来搜索,因为“如何在 Python 中重新启动命令窗口?”与您实际询问的内容无关。
  • 你能提供任何可能的上下文吗?
  • 听起来像是另一种尝试将编码习惯从他们的原生环境转移到没有任何意义的环境。
  • 如果您只是关心一些大型对象(图像或其他大型数组),您可以在完成后del 他们。如果您只是担心命名空间混乱,您可能应该重新考虑使用这么多名称的设计。例如,对于一系列图像转换,可能不需要保留每个中间步骤。
  • @S.Lott:控制台中的探索性科学分析。最终得到许多不需要的变量是很常见的(在尝试了一些事情之后,然后决定这不是一个相关的途径)。但在这种情况下,John La Rooy's answer 是最合适的。

标签: python


【解决方案1】:

删除变量的一种非常简单的方法是使用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

【讨论】:

    【解决方案2】:

    注意:你可能并不真正想要这个。

    globals() 函数返回一个字典,其中键是您可以命名的对象的名称(顺便说一下,值是这些对象的 ids) exec() 函数接受一个字符串并执行它,就好像您只是在 python 控制台中键入它一样。所以,代码是

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

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

    【讨论】:

    • 虽然此代码 sn-p 可以解决问题,但 including an explanation 有助于提高您的回复质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
    • 谢谢。现在好点了吗?
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      不,你最好重启解释器

      IPython 是捆绑解释器的绝佳替代品,并且具有通常有效的 %reset 命令

      【讨论】:

      • “不”是指我不应该这样做或者这是不可能的?如果你说我不应该这样做,你能解释一下原因吗?
      • +1:我到ctrl-d 然后pyt->tab 回到解释器只需要不到四分之一秒。没有理由在这里做任何花哨的事情。
      • %reset 适用于大多数变量,但对某些变量无效。对我来说,只有重新启动解释器才能保证清理所有内容。
      • 使用%reset -f 是非交互式的。 stackoverflow.com/questions/38798181/…
      【解决方案5】:

      在空闲的 IDE 中有 Shell/Restart Shell。 Ctrl-F6 就可以了。

      【讨论】:

        【解决方案6】:

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

        【讨论】:

        • 在 5.05 版中,它位于 Tools/Preferences/Run 下。
        【解决方案7】:
        from IPython import get_ipython;   
        get_ipython().magic('reset -sf')
        

        【讨论】:

        • 或者干脆%reset -sf
        • 实际上,当您使用 anaconda 提示符运行您的 python 脚本时,%reset -sf 命令不起作用并引发错误(即使您使用了 try-except;它不起作用)。你可以试试同样的,你会看到的。但是,在所有可能的情况下,使用 ipython 库都会解决这个问题。
        【解决方案8】:

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

        这个概念被称为namespace,它非常好,它进入了Zen of Python

        命名空间是一个很棒的主意 -- 让我们做更多的事情!

        同样可以使用魔术命令%reset -f 重置IPython 的命名空间。 (-f 的意思是“强制”;换句话说,“不要问我是否真的要删除所有变量,就这样做。”)

        【讨论】:

        • 我要补充一点:如果你把所有东西都放在一个主函数中(包括导入),你实际上会得到一个工作区,你可以通过退出该函数来重置它。我相信这确实是这个问题的目的。
        【解决方案9】:

        这是亚历克斯答案的修改版本。 我们可以使用以下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__
        【解决方案10】:

        以下命令序列确实会从当前模块中删除每个名称:

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

        我怀疑您是否真的想要这样做,因为“每个名称”都包含所有内置插件,因此在彻底清除之后您无能为力。请记住,在 Python 中实际上没有“变量”之类的东西——有 对象,有很多种(包括模块、函数、类、数字、字符串……),还有是名称,绑定到对象;该序列所做的是从模块中删除每个名称(当且仅当对它们的每个引用都刚刚被删除时,相应的对象才会消失)。

        也许您想更有选择性,但除非您想更具体,否则很难准确猜出您的意思。但是,举个例子:

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

        这个序列只留下私有或神奇的名称,包括包含所有内置名称的 __builtins__ 特殊名称。所以,内置插件仍然有效——例如:

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

        如您所见,名称 nfor 中的控制变量)也恰好存在(因为它每次都在 for 子句中重新绑定),因此命名可能更好控制变量_,例如,为了清楚地显示“它很特别”(另外,在交互式解释器中,名称_ 在提示符处输入每个完整表达式后无论如何都会重新绑定到该表达式的值,所以它不会长期存在;-)。

        无论如何,一旦你确定了你想要做什么,定义一个函数并将其放入你的启动文件中并不难(如果你只想要它在交互式会话中)或站点自定义文件(如果您希望在每个脚本中都使用它)。

        【讨论】:

        • 好吧,你总是可以在启动时保留原始字典的副本,然后删除已添加的名称;)但是我认为这是对动态系统的明显滥用,我想不出在一个非毫无意义的情况下这样做。
        • 哈哈,这太棒了...令人惊讶的是,这样做会失去多少功能,但通过int = (2).__class__str = ''.__class__、@987654332 之类的操作可以恢复多少功能@等...
        • @monoceres,您将如何命名该副本以及将其隐藏在哪里以免它也被擦除?-)
        • 我使用 Python 的次数越多,我就越喜欢它。它不仅是一门很棒的语言,你还可以花几个小时简单地摆弄它,让它做你真正不应该做的事情;-)
        • 也许我弄错了,但我遇到了一个问题:当你在某个时刻使用for n in dir(): ... if n[0]!='_': delattr(this, n) n=this 并在循环中删除它!因此,在下一次迭代中,您会收到错误尝试delattr(this,n),因为您刚刚删除了它! :) 所以它不能正常工作
        猜你喜欢
        • 2010-12-26
        • 2012-12-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-21
        相关资源
        最近更新 更多