【问题标题】:how to convert Python 2 unicode() function into correct Python 3.x syntax如何将 Python 2 unicode() 函数转换为正确的 Python 3.x 语法
【发布时间】: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 文档中找不到这个提示.....

【问题讨论】:

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

标签: python python-3.x python-unicode


【解决方案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() 的重要性
    猜你喜欢
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 2018-10-22
    • 1970-01-01
    • 2020-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多