【问题标题】:Variables inside a function not recreated at each function call函数内的变量不会在每次函数调用时重新创建
【发布时间】:2012-11-21 18:04:59
【问题描述】:

我正在回答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 对象(因此函数应该在每次运行时重新创建它),它似乎在函数返回后仍然存在,并且在函数返回时被重用而无需重新初始化被再次调用。同样,很明显wordigit 中的dict“数字”也是如此。

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

我注意到 Ipython 中的 Python 2.7.1 和新的 Python 2.7.3 解释器的这种行为

【问题讨论】:

  • 离题:更喜欢使用next(c) 而不是c.next(),因为next(c) 可以在python 2.x 和3.x 上运行。
  • @AshwiniChaudhary 我同意,但会指出 next() 作为内置函数直到 2.6 才出现,所以如果使用 2.5,你就不走运了

标签: python function variables scope python-2.7


【解决方案1】:

这看起来不对:

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

也许:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-07
    • 1970-01-01
    • 1970-01-01
    • 2021-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-18
    相关资源
    最近更新 更多