如何将 Python 2 unicode() 函数转换为正确的 Python 3.x 语法

Posted

技术标签:

【中文标题】如何将 Python 2 unicode() 函数转换为正确的 Python 3.x 语法【英文标题】:how to convert Python 2 unicode() function into correct Python 3.x syntax 【发布时间】:2016-12-06 10:14:57 【问题描述】:

我在我的 Python IDE 中启用了兼容性检查,现在我意识到继承的 Python 2.7 代码有很多对 unicode() 的调用,这在 Python 3.x 中是不允许的。

查看了Python2的docs,没有提示如何升级:

我现在不想切换到 Python3,但可能在将来。

代码包含大约 500 次对 unicode() 的调用

如何进行?

更新

用户 vaultah 阅读pyporting 指南的评论已获得数次投票。

我目前的解决方案是这样的(感谢 Peter Brittain):

from builtins import str

...我在 pyporting 文档中找不到这个提示.....

【问题讨论】:

docs.python.org/3/howto/pyporting.html @vaultah 这不是一个普遍的问题。这只是关于unicode() 的电话。在我目前工作的代码库中,有大约 700 次调用此方法。我该怎么办? 这个问题没有好的答案。如果你幸运的话,你可以删除对unicode 的调用,你就可以开始了。 Python 3 中的所有字符串都是 unicode。如果这不起作用,那么预计会有 lots 的工作。从 str 到 unicode 文字和字节的转换是迄今为止从 Python 2 切换到 3 时最不兼容的变化。 难道你不能在 Python 3 中定义自己的 unicode() 函数,除了 return str(arg) 之外什么都不做? 您可以将str 分配给unicode - unicode = str(不带括号)。它应该可以工作。 【参考方案1】:

正如 cmets 中已经指出的,已经有 advice on porting from 2 to 3。

最近不得不将我自己的一些代码从 2 移植到 3 并暂时保持每个代码的兼容性,我全心全意地推荐使用 python-future,它提供了一个很好的工具来帮助更新您的代码 (futurize)作为how to write cross-compatible code的明确指导。

在您的具体情况下,我会简单地将所有调用转换为 unicode 以使用 str,然后使用 import str from builtins。如今,任何值得一提的 IDE 都可以在一次操作中进行全局搜索和替换。

当然,如果您只想使用自动转换(并在代码中寻找其他潜在问题),那么 futurize 也应该捕捉到这种情况。

【讨论】:

是的,futurize 将帮助转换代码库; unicode() 调用将转换为 str() 调用,并在顶部导入 from builtins import str。请注意,通常确实会为 Python 2 上的 future 库添加安装类型要求(以提供向后移植的 builtins 模块)。 这将破坏 sqlalchemy 以及其他库。 “从 2 移植到 3 的建议”提到了很多 unicode,但并没有真正提到 unicode 函数本身。 @cowlinator 这就是为什么我还引用了 python 未来文档的原因。见python-future.org/compatible_idioms.html#unicode【参考方案2】:

你可以测试你运行的Python版本是否有unicode()这样的函数。如果没有,您可以为str() 函数创建一个unicode() 别名,它在Python 3 中的作用与unicode() 在Python 2 中的作用相同,因为所有字符串在Python 3 中都是unicode。

# Python 3 compatibility hack
try:
    unicode('')
except NameError:
    unicode = str

请注意,更完整的端口可能是一个更好的主意;详情请见the porting guide。

【讨论】:

是的,这个手工制作的解决方案应该可以工作。但我想我会使用 Peter Brittain 回答中解释的未来图书馆。 非常简单实用,完美解决了所提问题。此外,没有其他依赖项。【参考方案3】:

简答:将所有unicode 调用替换为str 调用。

长答案:在 Python 3 中,Unicode 被替换为字符串,因为它很丰富。如果您只使用 Python 3,则以下解决方案应该可以工作:

unicode = str
# the rest of your goes goes here

如果您同时使用 Python 2 或 Python 3,请改用它:

import sys
if sys.version_info.major == 3:
    unicode = str
# the rest of your code goes here

另一种方式:在命令行中运行它

$ 2to3 package -w

【讨论】:

【参考方案4】:

首先,作为一种策略,我会采用您的程序的一小部分并尝试移植它。您所描述的unicode 调用次数向我表明,您的应用程序比大多数应用程序更关心字符串表示,并且每个用例通常都不同。

重要的考虑是所有字符串在 Python 3 中都是 unicode。如果您使用 str 类型来存储“字节”(例如,如果它们是从文件中读取的),那么您应该知道这些在 Python3 中不是字节,而是以 unicode 字符开头。

我们来看几个案例。

首先,如果您根本没有任何非 ASCII 字符并且真的没有使用 Unicode 字符集,那很容易。您可以简单地将unicode() 函数更改为str()。这将确保作为参数传递的任何对象都被正确转换。然而,假设它是那么容易是一厢情愿的想法。

您很可能需要查看unicode() 的参数以了解它是什么,并确定如何处理它。

例如,如果您在 Python 2 中从文件中读取 UTF-8 字符并将其转换为 Unicode,您的代码将如下所示:

data = open('somefile', 'r').read()
udata = unicode(data)

但是在Python3中,read()返回Unicode数据开头,打开文件时必须指定Unicode解码:

udata = open('somefile', 'r', encoding='UTF-8').read()

如您所见,仅在移植时转换 unicode() 可能在很大程度上取决于应用程序进行 Unicode 转换的方式和原因、数据的来源和目的地。

Python3 为字符串表示带来了更高的清晰度,这是受欢迎的,但会使移植变得令人生畏。例如,Python3 有一个正确的 bytes 类型,你可以像这样将字节数据转换为 unicode:

udata = bytedata.decode('UTF-8')

或使用相反的转换将 Unicode 数据转换为字符形式。

bytedata = udata.encode('UTF-8')

我希望这至少有助于确定策略。

【讨论】:

很好的答案,它解释了正确替换 unicode() 的重要性

以上是关于如何将 Python 2 unicode() 函数转换为正确的 Python 3.x 语法的主要内容,如果未能解决你的问题,请参考以下文章

Python 2如何将values_list操作返回的unicode列表更改为字符串列表

Python 2 如何将 values_list 操作返回的 unicode 列表更改为字符串列表

盘点Python中易忽略的函数

Python 2 maketrans() 函数不适用于 Unicode:实际上是“参数长度不同”

python中怎样将unicode转换成原来的中文?

unicode 在 Python 内部是如何表示的?