在Python中,我经常以类似于此的方式重用变量:
files = files[:batch_size]
我喜欢这种技术,因为它可以帮助我减少需要跟踪的变量数量。
从来没有遇到任何问题,但我想知道我是否缺少潜在的缺点,例如表演等。
答案 0 :(得分:6)
重用变量名没有技术缺点。但是,如果您重复使用变量并更改其“目的”,则可能会使其他人阅读您的代码时感到困惑(特别是如果他们错过了重新分配)。
在您提供的示例中,您会发现在拼接时实际上正在生成一个全新的列表。在GC收集该列表的旧副本之前,该列表将存储在内存中两次(除了拼接的内容)。另一种方法是迭代该列表并在到达batch_size
元素时停止,而不是完成列表,或者更简洁,del files[batch_size:]
。
答案 1 :(得分:5)
有关该特定示例的一些信息:如果您只想迭代,映射或过滤结果,可以使用生成器来避免数组副本:
import itertools
files = itertools.islice(files, batch_size)
对于一般情况:无论是将新值分配给现有名称还是新名称都应该完全没有区别(至少从解释器/ 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
在Python 3中可以观察到相同的内容。
事实上,func1
甚至可能会更快一些,因为之前已经看到名称files
,并且可能已经在某个变量查找缓存中。
答案 2 :(得分:1)
重复使用变量确实没有太多的缺点,除了你不会经历许多优点。无论如何都要运行Python GC以收集旧对象,因此当覆盖变量时不会立即获得内存增益,这与静态编译语言(如C)不同,其中重用变量会完全阻止内存分配新对象。
此外,您可以真正混淆代码的任何未来读者,他们通常希望新对象具有新名称(垃圾收集语言的副产品)。
答案 3 :(得分:1)
缺点是,你不能使用:
file_rest = files[batch_size:]
关于表现,没有任何缺点。相反:您甚至可以通过在同一名称空间中避免哈希冲突来提高性能。
在另一个背景下有一个SO-post。