函数内部的变量在每次函数调用时都不会重新创建

时间:2012-11-21 18:04:59

标签: python function variables scope python-2.7

我正在回答this question,我的解决方案如下(我没有发布这个答案):

def wordigit(w):
    digits = {}
    c = itertools.count(1)
    for char in w:
        if w not in digits:
            digits[char] = c.next()
    return ''.join(str(i) for i in (digits[char] for char in w))

print ' '.join(wordigit(w) for w in s.split())
乍一看,这看起来是正确的。但是我得到了一个错误的结果:

In [236]: ' '.join(wordigit(w) for w in s.split())
Out[236]: '12345 14345 33345' # notice the numbers in the second "word". 1-4 is not a legal progression for itertools.count. It should have been 12324 instead of 14345

我在IPython中开发了这个解决方案。认为这可能是IPython在幕后进行的一些优化的错误,我启动了一个python解释器来查看它说的内容。我还认为列表理解可能会导致一些异常行为。所以我尝试两次调用wordigit - 在两个不相等的字符串中分别调用一次,得到以下结果:

>>> def wordigit(w):
...     digits = {}
...     c = itertools.count(1)
...     for char in w:
...         if w not in digits:
...             digits[char] = c.next()
...     return ''.join(str(i) for i in (digits[char] for char in w))
... 
>>> wordigit('areyo')
'12345'
>>> wordigit('uanap')
'14345'

所以看起来即使我在函数中创建itertools.count对象(因此函数应该在每次运行时都重新创建它),它在函数返回后会以某种方式持续存在并在没有重新初始化的情况下重新使用该函数再次被调用。同样,很明显,dict中的wordigit“数字”也是如此。

这是怎么回事?不知何故,这种行为对我来说没有意义。

我注意到Ipython中的Python 2.7.1和新的Python 2.7.3解释器

的这种行为

1 个答案:

答案 0 :(得分:4)

这看起来不对:

for char in w:
    if w not in digits:
      ^^^

也许:

for char in w:
    if char not in digits: 
       ^^^^