在Python中,我经常以类似于此的方式重用变量:
files = files[:batch_size]
Run Code Online (Sandbox Code Playgroud)
我喜欢这种技术,因为它可以帮助我减少需要跟踪的变量数量.
没有任何问题,但我想知道我是否缺少潜在的缺点,例如性能等.
重用变量名称没有技术缺点.但是,如果您重复使用变量并更改其"目的",则可能会使其他人阅读您的代码时感到困惑(特别是如果他们错过了重新分配).
但是,在您提供的示例中,您会发现在拼接时实际上正在生成一个全新的列表.在GC收集该列表的旧副本之前,该列表将存储在内存中两次(除了拼接的内容).另一种方法是迭代该列表并在到达第batch_sizeth个元素时停止,而不是完成列表,或者甚至更简洁del files[batch_size:].
有关该特定示例的一些信息:如果您只想迭代,映射或过滤结果,可以使用生成器来避免数组副本:
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之前已经看到过该名称,并且可能已经存在于某些变量查找缓存中.