在Python中重用变量

jld*_*ont 7 python

在Python中,我经常以类似于此的方式重用变量:

files = files[:batch_size]
Run Code Online (Sandbox Code Playgroud)

我喜欢这种技术,因为它可以帮助我减少需要跟踪的变量数量.

没有任何问题,但我想知道我是否缺少潜在的缺点,例如性能等.

che*_*ken 8

重用变量名称没有技术缺点.但是,如果您重复使用变量并更改其"目的",则可能会使其他人阅读您的代码时感到困惑(特别是如果他们错过了重新分配).

但是,在您提供的示例中,您会发现在拼接时实际上正在生成一个全新的列表.在GC收集该列表的旧副本之前,该列表将存储在内存中两次(除了拼接的内容).另一种方法是迭代该列表并在到达第batch_sizeth个元素时停止,而不是完成列表,或者甚至更简洁del files[batch_size:].


Nik*_* B. 5

有关该特定示例的一些信息:如果您只想迭代,映射或过滤结果,可以使用生成器来避免数组副本:

import itertools
files = itertools.islice(files, batch_size)
Run Code Online (Sandbox Code Playgroud)

至于一般情况:无论是将新值分配给现有名称还是新名称都应该完全没有区别(至少从解释器/ VM的角度来看).两种方法都产生几乎完全相同的字节码:

Python 2.7.2 (default, Nov 21 2011, 17:25:27) 
[GCC 4.6.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import dis
>>> def func1(files):
...   files = files[:100]
... 
>>> def func2(files):
...   new_files = files[:100]
... 
>>> dis.dis(func1)
  2           0 LOAD_FAST                0 (files)
              3 LOAD_CONST               1 (100)
              6 SLICE+2             
              7 STORE_FAST               0 (files)
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE        
>>> dis.dis(func2)
  2           0 LOAD_FAST                0 (files)
              3 LOAD_CONST               1 (100)
              6 SLICE+2             
              7 STORE_FAST               1 (new_files)
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE        
Run Code Online (Sandbox Code Playgroud)

在Python 3中也可以观察到相同的情况.

事实上,func1甚至可能会更快一点,因为files之前已经看到过该名称,并且可能已经存在于某些变量查找缓存中.