gpt4 book ai didi

Python闭包+全局奇异

转载 作者:太空狗 更新时间:2023-10-29 18:31:47 24 4
gpt4 key购买 nike

我希望这个小片段打印“为什么这不起作用?”有人能帮我理解为什么这不像我预期的那样起作用吗?如果这很重要,我正在使用 Python 2.6。

class WhyDoesntThisWork(object):
def outer(self):
acc = ''
def inner(msg):
global acc
acc = acc + msg
inner("Why doesn't")
inner(" this work?")
print acc
WhyDoesntThisWork().outer()
  • 如果我包含 global 语句,我会得到一个 NameError: global name 'acc' is not defined
  • 如果我不包含 global 语句,我会得到一个 UnboundLocalError: local variable 'acc' referenced before assignment

最佳答案

不知道为什么上面那么多评论都是正确答案,却没人敢写出真实的答案,所以我就写下了。

class ThisWorksNow(object):
def outer(self):
acc = []
def inner(msg):
acc.append(msg)
inner("Why doesn't")
inner(" this work?")
print "".join(acc)
ThisWorksNow().outer()

有什么区别?

为闭包中的对象指定名称在 Python 2.x 中不起作用,因为缺少 Py3 关键字 nonlocal,因此我们必须找到解决方法。

如果我们必须保持名称到对象的绑定(bind)不变,我们必须更改其他内容。在本例中,它是对象,我们向其添加要添加的内容。

print 行不是很优雅;也许打印其内容连接的对象可能更合适。

class StringBuilder(list): # class name stolen from Java
def __str__(self):
"""this makes the object printable in a way which represents the concatenated string"""
return "".join(self)
@property
def string(self):
"""this gives us a property which represents the concatenated string"""
return "".join(self)
# use whatever suits you better, one or both

有了这个,我们可以做到:

class ThisWorksNow(object):
def outer(self):
acc = StringBuilder()
def inner(msg):
acc.append(msg)
inner("Why doesn't")
inner(" this work?")
print acc
print acc.string # depending on what you take above
ThisWorksNow().outer()

编辑(附加):为什么 global 不起作用?

我们也可以通过 global 实现这一点,但有两个缺点。

  1. acc 在我们使用它的两个地方都必须是全局的

    class WhyDoesntThisWork(object):
    def outer(self):
    global acc
    acc = ''
    def inner(msg):
    global acc
    acc = acc + msg

    据此,我们将 acc 事件“提升”到“global”级别。

  2. acc 可以从外部修改。

    如果我们在其他地方执行 global acc,或者我们在模块级别使用 acc,我们的过程可能会被篡改。应该避免这种情况。

关于Python闭包+全局奇异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11164149/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com