Python嵌套函数作用域 [英] Python nested function scopes

查看:295
本文介绍了Python嵌套函数作用域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的代码:

I have code like this:

def write_postcodes(self):
    """Write postcodes database. Write data to file pointer. Data 
    is ordered. Initially index pages are written, grouping postcodes by
    the first three characters, allowing for faster searching."""
    status("POSTCODE", "Preparing to sort...", 0, 1)
    # This function returns the key of x whilst updating the displayed 
    # status of the sort.
    ctr = 0
    def keyfunc(x):
        ctr += 1
        status("POSTCODE", "Sorting postcodes", ctr, len(self.postcodes))
        return x
    sort_res = self.postcodes[:]
    sort_res.sort(key=keyfunc)

但ctr用NameError响应:

But ctr responds with a NameError:

Traceback (most recent call last):
  File "PostcodeWriter.py", line 53, in <module>
    w.write_postcodes()
  File "PostcodeWriter.py", line 47, in write_postcodes
    sort_res.sort(key=keyfunc)
  File "PostcodeWriter.py", line 43, in keyfunc
    ctr += 1
UnboundLocalError: local variable 'ctr' referenced before assignment

我该如何解决这个问题?我认为nester范围会允许我这样做。我尝试过使用'global',但它仍然不起作用。

How can I fix this? I thought nester scopes would have allowed me to do this. I've tried with 'global', but it still doesn't work.

推荐答案

由于嵌套函数不能重新绑定一个非本地名称(在Python 2中;在Python 3中,您可以使用 nonlocal 语句来启用该名称),则需要执行递增而无须重新绑定(通过保留计数器作为某个裸号的项目或属性,不是作为裸号本身)。例如:

Since the nested function can't rebind a nonlocal name (in Python 2; in Python 3, you'd use the nonlocal statement to enable that), you need to perform your incrementing without barename rebinding (by keeping the counter as an item or attribute of some barename, not as a barename itself). For example:

...
ctr = [0]
def keyfunc(x):
    ctr[0] += 1
    status("POSTCODE", "Sorting postcodes", ctr, len(self.postcodes))
    return x
...

当然可以使用 ctr [0] 现在重新使用裸露 ctr

and of course use ctr[0] wherever you're using bare ctr now elsewhere.

这篇关于Python嵌套函数作用域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆