Python 更喜欢未分配的本地函数而不是内置函数

标签 python compatibility

以下 Python 脚本适用于 Python 2.3 和 Python 2.4(它们没有内置的 all() 定义):

#! /usr/bin/env python
# vim: set fileencoding=utf-8
# (c) Uwe Kleine-König
# GPLv2

import locale
import sys

f = file(sys.argv[1])
data = f.read()

def len_utf8_char(data):
    if not 'all' in dir(__builtins__):
        def all(seq):
            for i in seq:
                if not i:
                    return False
            return True

    def check_cont(num):
        if all(map(lambda c: ord(c) >= 0x80 and ord(c) <= 0xbf, data[1:num])):
            return num
        else:
            return -1

    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)

i = 0
maxl = 0
while i < len(data):
    l = len_utf8_char(data[i:])
    if l < 0:
        prefenc = locale.getpreferredencoding()
        if prefenc not in ('UTF-8', 'ANSI_X3.4-1968'):
            print prefenc
        else:
            print 'ISO-8859-1'
        sys.exit(0)

    if maxl < l:
        maxl = l
    i += l

if maxl > 1:
    print 'UTF-8'
else:
    print '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

删除 all 的兼容性定义修复了 Python 2.5+ 的问题。 我想知道为什么 Python 在这种情况下不选择内置的 all() 。有人可以解释一下吗?

最佳答案

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

def all 为变量名all 赋值。尽管赋值是在 if-block 内部,all 在所有情况下都被视为局部变量(无论 if-block 是否是稍后执行)。

当 if block 未执行时,all 成为未绑定(bind)的局部变量,从而引发 NameError。

如果将 if not 'all' ... block 移到 def len_utf8_char 之外,则 你会避免这个问题。

关于Python 更喜欢未分配的本地函数而不是内置函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6617354/

相关文章:

python - 如果函数调用在 python2.x/3.x 中太长,如何缩进

python - 前后端分离时的Django CSRF

python - 在 Plone 中添加用户之间关系的首选方式是什么?

javascript - 如何使用 JavaScript 或 Selenium 检查页面上是否存在警报

Windows 7 x64 上的 Delphi 问题?

python - 带有 MNIST 的 LSTM 示例

perl - 为什么 MIME::Lite->new() 在我的服务器中不起作用?

http - 重定向到同一个 URL 是否安全?

Windows:如何创建自定义 appcompat 垫片(应用程序修复)?

linux - 共享库兼容性问题