删除所有变量,除了一个for循环,没有污染


%reset
%reset -f

%reset_selective a
%reset_selective -f a

是Matlab命令"clear all"的有用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)

?

限制变量作用域的一般方法是在函数中使用它们。函数完成后,其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的一个简单方法是给临时变量一个独特的名字,比如一个regex很容易找到的前缀。例如

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

获得外壳和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字典中查找名字以便删除它们。注意,这个删除代码创建了一些变量,dellist, i, ip, user_ns

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

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

一般来说,最好使用函数来限制变量的作用域,而不是使用del()%reset。偶尔,如果处理非常大的数组,那种占用一meg内存并可能产生内存错误的数组,我可能会使用dela=None来删除它们。但是普通的变量不需要特别的注意(即使在ipython会话中也不需要注意)。

我正在寻找相同任务的帮助,我注意到hpaulj的评论,关于%who_ls返回一个名称列表,然后我记得一些关于R中的metaprogrammin的命令eval(解析器(text=text)),然后我在python中寻找和等效的前一个命令,使用变量的名称删除lst_arch中的所有变量(R的eval(parse(text=text))在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中过滤某些变量,我们可以使用正则表达式或类似的东西来删除我们想要删除的变量

最新更新