【问题标题】:Python: delete all variables except one for loops without contaminationsPython:删除所有变量,除了一个没有污染的for循环
【发布时间】:2017-01-11 02:55:43
【问题描述】:
%reset
%reset -f

%reset_selective a
%reset_selective -f a

是Matlab命令“清除所有”的有用Python替代品,其中“-f”表示“强制而不要求确认”,“_selective”可以与

结合使用
who_ls

有选择地删除工作区中的变量,如https://ipython.org/ipython-doc/3/interactive/magics.html 所示。

现在我正在管理循环,我将在其中定义大量变量,例如

for j in range(1000):
    a = crazy_function1()
    b = crazy_function2()
    ...
    m = crazy_function18()
    n = crazy_function19()
    ...
    z = crazy_functionN()

在每个循环结束时,我想删除所有变量,除了 Python 工作区的标准变量和我引入的一些变量(在这个例子中只有 m 和 n)。这将避免污染和内存负担,从而使代码更加高效和安全。

我看到“who_ls”的结果看起来像一个列表,因此我想在一个循环中删除所有不等于 m 或 n 的变量

for j in range(1000):
    a = crazy_function1()
    b = crazy_function2()
    ...
    m = crazy_function18()
    n = crazy_function19()
    ...
    z = crazy_functionN()
    if who_ls[j] != m or who_ls[j] != n:
         %reset_selective -f who_ls[j]

但它不起作用,因为 who_ls 看起来像一个列表,但它不像一个列表。您将如何修改最后几行代码? 有没有类似的

 %reset_selective -f, except variables(m, n)

?

【问题讨论】:

  • 为什么不将不必要的存储到字典或列表中呢?然后,您可以一次将其全部删除。您确定删除这些变量会更有效吗?我相信 MATLAB 不会将该内存还给操作系统,而且我不知道 ipython 的垃圾收集在同一场景中是如何工作的。
  • 将所有不必要的变量存储在字典中是个好主意,我相信系统越复杂,您对它的控制就越少,最终,您不能拥有 100 % 控制你在做什么。出于这个原因,我认为删除不必要的变量很重要。
  • @Two-BitAlchemist 如果 ipython 的内存管理和交互式 shell 完全一样,那么 OK。但我很确定它不是(例如,考虑 ipython 中存在的历史和 Out[n] 引用)。话题性是另一个问题,尽管我不相信特定于 ipython 的问题是题外话。无论如何,我们不必同意:)
  • @AndrasDeak 对我来说,如果 OP 真的想要这样做(包括 Out 在内的所有引用都已删除),我会认为这听起来像是不切实际的寻求清除 Python 的内存,我会承认这是一个可怕的欺骗目标。
  • @Two-BitAlchemist 坦率地说,我相信 OP 只是“想要高效”,并认为“删除不必要的变量”会有所帮助。无论这意味着什么,以及它实际上做了什么。

标签: python ipython


【解决方案1】:

我正在为同一任务寻求帮助,我注意到 hpaulj 的评论,关于 %who_ls 返回一个名称列表,然后我想起了 R 中使用命令 eval(parser(text = text)) 的元编程,然后我在 python 中寻找和前面的命令等效的方法,使用变量名称删除 lst_arch 中的所有变量 (R's eval(parse(text=text)) equivalent in Python)

    a = 1
    b = 1

    lst_arch = %who_ls
    lst_arch.append('lst_arch')
    lst_arch.append('x')

    for x in lst_arch:
        exec(f'del(' + x + ')')

如果我们想从 lst_arch 中过滤某些变量,我们可以使用正则表达式或类似的东西来删除我们想要删除的那些变量。

【讨论】:

    【解决方案2】:

    限制变量范围的常规方法是在函数中使用它们。函数完成后,其locals 消失。

    In [71]: def foo():
        ...:     a=1
        ...:     b=2
        ...:     c=[1,2,3]
        ...:     d=np.arange(12)
        ...:     print(locals())
        ...:     del(a,b,c)
        ...:     print(locals())
        ...:     
    In [72]: foo()
    {'d': array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11]), 'c': [1, 2, 3], 'a': 1, 'b': 2}
    {'d': array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])}
    

    ===================

    %who_ls返回一个列表,可以在RHS上使用,如

    xx = %who_ls
    

    然后可以迭代该列表。但请注意,这是一个变量名列表,而不是变量本身。

    for x in xx: 
        if len(x)==1:
            print(x)
            # del(x)  does not work
    

    显示所有长度为 1 的名称。

    =======================

    使用%reset_selective 的一种简单方法是为临时变量指定一个独特的名称,例如正则表达式可以轻松找到的前缀。例如

    In [198]: temp_a, temp_b, temp_c, x, y = 1,'one string',np.arange(10), 10, [1,23]
    In [199]: who_ls
    Out[199]: ['np', 'temp_a', 'temp_b', 'temp_c', 'x', 'y']
    In [200]: %reset_selective -f temp 
    In [201]: who_ls
    Out[201]: ['np', 'x', 'y']
    

    =====================

    以下是从名称列表中执行此删除操作的示例。请记住,我们尝试删除的实际变量与其名称之间存在差异。

    制作一些变量,以及要删除的名称列表

    In [221]: temp_a, temp_b, temp_c, x, y = 1,'one string',np.arange(10), 10, [1,23]
    In [222]: dellist=['temp_a', 'temp_c','x']
    

    获取 shell 和 user_nswho_ls 使用来自 self.shell.user_ns 的密钥。

    In [223]: ip=get_ipython()
    In [224]: user_ns=ip.user_ns
    
    In [225]: %who_ls
    Out[225]: ['dellist', 'i', 'ip', 'np', 'temp_a', 'temp_b', 'temp_c', 'user_ns', 'x', 'y']
    
    In [226]: for i in dellist:
         ...:     del(user_ns[i])
         ...:     
    In [227]: %who_ls
    Out[227]: ['dellist', 'i', 'ip', 'np', 'temp_b', 'user_ns', 'y']
    

    所以我们必须在user_ns 字典中查找名称才能删除它们。请注意,此删除代码会创建一些变量,dellistiipuser_ns

    ==============

    您担心多少变量?他们多大?标量、列表、numpy 数组。十几个可以用字母命名的标量不会占用太多内存。如果在生成变量时存在任何模式,那么将它们收集到列表或字典中可能更有意义,而不是尝试为每个变量指定一个唯一的名称。

    一般来说,最好使用函数来限制变量的范围,而不是使用del()%reset。有时,如果处理非常大的数组,即占用大量内存并可能产生内存错误的数组,我可能会使用del 或仅使用a=None 来删除它们。但普通变量不需要特别注意(即使是在持续几天的ipython 会话中也不需要)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-03
      • 1970-01-01
      • 1970-01-01
      • 2021-11-11
      • 2022-10-13
      • 2013-10-08
      • 1970-01-01
      相关资源
      最近更新 更多