名称错误:全局名称'unicode'未定义 - 在Python 3中。

186

我正在尝试使用一个名为bidi的Python软件包。在该软件包的一个模块(algorithm.py)中有一些代码行引发了错误,尽管它是该软件包的一部分。

以下是导致错误的代码行:

# utf-8 ? we need unicode
if isinstance(unicode_or_str, unicode):
    text = unicode_or_str
    decoded = False
else:
    text = unicode_or_str.decode(encoding)
    decoded = True

这里是错误信息:

Traceback (most recent call last):
  File "<pyshell#25>", line 1, in <module>
    bidi_text = get_display(reshaped_text)
  File "C:\Python33\lib\site-packages\python_bidi-0.3.4-py3.3.egg\bidi\algorithm.py",   line 602, in get_display
    if isinstance(unicode_or_str, unicode):
NameError: global name 'unicode' is not defined

我该如何重写这段代码,使它能在Python3中运行?另外,如果有人在Python 3中使用了bidi包,请告诉我是否遇到了类似的问题。感谢您的帮助。

7个回答

286

Python 3将unicode类型更名为str,旧的str类型被bytes替换。

if isinstance(unicode_or_str, str):
    text = unicode_or_str
    decoded = False
else:
    text = unicode_or_str.decode(encoding)
    decoded = True

您可能想阅读Python 3移植HOWTO了解更多细节。此外,还有Lennart Regebro的《移植到Python 3:深入指南》,可以免费在线浏览。

最后,您也可以尝试使用2to3工具,看它如何将代码转换给你。


那我应该写成:if isinstance(unicode_or_str, str) 吗?'unicode_or_str' 怎么处理? - TJ1
1
变量名在这里并不重要;if isinstance(unicode_or_str, str) 应该可以正常工作。重新命名变量名是可选的。 - Martijn Pieters

50

如果你需要像我一样让脚本在Python2和3上都能正常运行,这个可能对某些人有所帮助。

import sys
if sys.version_info[0] >= 3:
    unicode = str

然后就可以做例如

foo = unicode.lower(foo)

2
这是正确的想法,很好的答案。只需添加一个细节,如果您正在使用six库来管理Python 2/3兼容性,您可以这样做:if six.PY3: unicode = str而不是sys.version_info的内容。这对于防止与Python 3中未定义unicode相关的linter错误也非常有帮助,而无需特殊的linter规则例外。 - ely

25
你可以使用 six 库来同时支持 Python 2 和 3:
import six
if isinstance(value, six.string_types):
    handle_string(value)

4

可以将 unicode 替换为 u''.__class__ 来处理 Python 3 中缺失的 unicode 类。对于 Python 2 和 3,您都可以使用以下构造:

isinstance(unicode_or_str, u''.__class__)

或者
type(unicode_or_str) == type(u'')

根据您的后续处理方式,考虑不同的结果:

Python 3

>>> isinstance(u'text', u''.__class__)
True
>>> isinstance('text', u''.__class__)
True

Python 2

>>> isinstance(u'text', u''.__class__)
True
>>> isinstance('text', u''.__class__)
False

2

希望您正在使用Python 3,因为默认情况下Str是Unicode的,所以请使用字符串Str函数替换Unicode函数。

if isinstance(unicode_or_str, str):    ##Replaces with str
    text = unicode_or_str
    decoded = False

2
请考虑撤回或更新您的答案。没有理由让Python2用户落后或破坏Python3。该答案不像@atm的答案一样保留BC。 - MrMesees

1

如果第三方库使用unicode,而且你无法更改它们的源代码,那么以下的猴子补丁可以在模块中使用str来替代unicode

import <module>
<module>.unicode = str

0

你可以在Python2或Python3中使用这个

type(value).__name__ == 'unicode':

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接