Python更喜欢未分配的局部函数而不是内置函数

Python更喜欢未分配的局部函数而不是内置函数,python,compatibility,Python,Compatibility,以下Python脚本与Python 2.3和Python 2.4(它们没有all()的内置定义)配合使用效果良好: !/usr/bin/env python #vim:设置文件编码=utf-8 #(c)Uwe Kleine-König #GPLv2 导入区域设置 导入系统 f=文件(sys.argv[1]) data=f.read() def len_utf8_字符(数据): 如果目录中不是“全部”(\uuuu内置\uuuuu): def all(序列号): 对于下文中的i: 如果不是,我: 返

以下Python脚本与Python 2.3和Python 2.4(它们没有
all()
的内置定义)配合使用效果良好:

!/usr/bin/env python
#vim:设置文件编码=utf-8
#(c)Uwe Kleine-König
#GPLv2
导入区域设置
导入系统
f=文件(sys.argv[1])
data=f.read()
def len_utf8_字符(数据):
如果目录中不是“全部”(\uuuu内置\uuuuu):
def all(序列号):
对于下文中的i:
如果不是,我:
返回错误
返回真值
def检查控制(数值):
如果all(map)(λc:ord(c)>=0x80且ord(c)1:
打印“UTF-8”
其他:
打印“ANSI_X3.4-1968”
现在,在Python 2.5及更高版本中,失败如下:

$ python2.5 guess-charmap guess-charmap
Traceback (most recent call last):
  File "guess-charmap", line 43, in <module>
    l = len_utf8_char(data[i:])
  File "guess-charmap", line 30, in len_utf8_char
    return check_cont(2)
  File "guess-charmap", line 21, in check_cont
    if all(map(lambda c: ord(c) >= 0x80 and ord(c) <= 0xbf, data[1:num])):
NameError: free variable 'all' referenced before assignment in enclosing scope
$python2.5 guess charmap guess charmap
回溯(最近一次呼叫最后一次):
文件“guess charmap”,第43行,在
l=len_utf8_char(数据[i:]
文件“guess charmap”,第30行,len_utf8_char
退货检查续(2)
文件“guess charmap”,第21行,检查内容

如果all(map)(lambda c:ord(c)>=0x80,并且ord(c),因为在all()之后定义函数时,函数仍然在局部范围内。 为什么在一个函数中有这么多函数定义? 为什么要定义all()呢? 为什么不使用dict呢

   if ord(data[0]) < 128:
        # ASCII char
        return 1
    elif ord(data[0]) & 0xe0 == 0xc0:
        return check_cont(2)
    elif ord(data[0]) & 0xf0 == 0xe0:
        return check_cont(3)
    elif ord(data[0]) & 0xf8 == 0xf0:
        return check_cont(4)
    elif ord(data[0]) & 0xfc == 0xf8:
        return check_cont(5)
    elif ord(data[0]) & 0xfe == 0xfc:
        return check_cont(6)
如果作战需求文件(数据[0])<128:
#ASCII字符
返回1
elif ord(数据[0])&0xe0==0xc0:
退货检查续(2)
elif ord(数据[0])&0xf0==0xe0:
退货支票续(3)
elif ord(数据[0])&0xf8==0xf0:
退货检查续(4)
elif ord(数据[0])&0xfc==0xf8:
退货支票续(5)
elif ord(数据[0])&0xfe==0xfc:
退货检查续(6)

事实上,我会要求重写这段代码,它既复杂又烦人。

当Python解析函数体时,它会查找赋值中使用的变量名。除非使用
全局
变量声明,否则所有这些变量都假定为局部变量

def all
为变量名
all
赋值。尽管赋值在
if块
中,但在所有情况下
all
都被视为局部变量(无论以后是否执行
if块

如果不执行if块,
all
将成为一个未绑定的局部变量,从而引发NameError

如果将
If not'all'…
块移到
def len\u utf8\u char
之外,则
您将避免此问题。

与变量发生此问题的原因相同;编译器已将其标记为函数的本地,因此希望它是本地。如果要解决此问题,只需在
else
子句中执行
all=\uu内置项.all

您可以将
all
的定义放在模块级别l例如:

try:
    all
except NameError:
    def all(seq):
        for i in seq:
            if not i:
                return False
        return True

我不明白你的第一句话。其余的似乎是对的,但离题了。或者只是在
len\u utf8\u char
之外定义
all
。这不是一个闭包,没有理由需要在里面。看起来你在尝试检测字符编码。你有没有看过像chardet这样的库,它可以更快、更灵活地实现这一点是吗?我想是的,但在文档中找不到这种行为。可能就是找不到正确的搜索词。
try:
    all
except NameError:
    def all(seq):
        for i in seq:
            if not i:
                return False
        return True