简体   繁体   English

在Python中重用变量

[英]Reusing variables in Python

In Python, I often reuse variables in manner analogous to this: 在Python中,我经常以类似于此的方式重用变量:

files = files[:batch_size]

I like this technique because it helps me cut on the number of variables I need to track. 我喜欢这种技术,因为它可以帮助我减少需要跟踪的变量数量。

Never had any problems but I am wondering if I am missing potential downsides eg performance etc. 没有任何问题,但我想知道我是否缺少潜在的缺点,例如性能等。

There is no technical downside to reusing variable names. 重用变量名称没有技术缺点。 However, if you reuse a variable and change its "purpose", that may confuse others reading your code (especially if they miss the reassignment). 但是,如果您重复使用变量并更改其“目的”,则可能会使其他人阅读您的代码时感到困惑(特别是如果他们错过了重新分配)。

In the example you've provided, though, realize that you are actually spawning an entirely new list when you splice. 但是,在您提供的示例中,您会发现在拼接时实际上正在生成一个全新的列表。 Until the GC collects the old copy of that list, that list will be stored in memory twice (except what you spliced out). 在GC收集该列表的旧副本之前,该列表将存储在内存中两次(除了拼接的内容)。 An alternative is to iterate over that list and stop when you reach the batch_size th element, instead of finishing the list, or even more succinctly, del files[batch_size:] . 另一种方法是迭代该列表并在到达batch_size th元素时停止,而不是完成列表,或者甚至更简洁, del files[batch_size:]

Some info on that specific example: If you just want to iterate, map or filter the result, you can use a generator to avoid an array copy: 有关该特定示例的一些信息:如果您只想迭代,映射或过滤结果,可以使用生成器来避免数组副本:

import itertools
files = itertools.islice(files, batch_size)

As for the general case: Whether you assign the new value to an already existing name or to a new name should make absolutely no difference (at least from the point of view of the interpreter/VM). 至于一般情况:无论是将新值分配给现有名称还是新名称都应该完全没有区别(至少从解释器/ VM的角度来看)。 Both methods produce almost the exact same bytecode: 两种方法都产生几乎完全相同的字节码:

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        

The same can be observed in Python 3. 在Python 3中也可以观察到相同的情况。

In fact, func1 could even be a bit faster, because the name files has been seen before and could already be in some variable lookup cache. 事实上, func1甚至可能会更快一些,因为之前已经看到过名称files ,并且可能已经存在于某些变量查找缓存中。

There really aren't going to be many downsides to reusing variables, except that you're not going to experience many advantages either. 重复使用变量确实没有太多的缺点,除了你不会经历许多优点。 The Python GC is going to have to run anyway to collect the old object, so there isn't an immediate memory gain when you override the variable, unlike in statically-compiled languages such as C, where reusing a variable prevents memory allocation entirely for the new object. 无论如何都要运行Python GC以收集旧对象,因此当覆盖变量时不会立即获得内存增益,这与静态编译语言(如C)不同,其中重用变量会完全阻止内存分配新的对象。

Further, you can truly confuse any future readers of your code, who generally expect new objects to have new names (a byproduct of garbage-collected languages). 此外,您可以真正混淆代码的任何未来读者,他们通常希望新对象具有新名称(垃圾收集语言的副产品)。

The downside would be, that you can't use: 缺点是,你不能使用:

file_rest = files[batch_size:]

Regarding performance there is no downside. 关于表现,没有任何缺点。 On the contrary: you might even improve performance by avoiding hash collision in the same name-space. 相反:您甚至可以通过避免在相同名称空间中的哈希冲突来提高性能。

There was a SO-post regarding this in an other context. 在另一个背景下,有一篇关于此的SO帖子

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM