如何将 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 列表更改为字符串列表