Python更喜欢未分配的局部函数而不是内置函数
以下Python脚本与Python 2.3和Python 2.4(它们没有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: 如果不是,我: 返
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