【问题标题】:(unicode error) 'unicodeescape' codec can't decode bytes - string with '\u'(unicode 错误)“unicodeescape”编解码器无法解码字节 - 带有“\u”的字符串
【发布时间】:2011-11-27 23:11:20
【问题描述】:

为 Python 2.6 编写代码,但考虑到 Python 3,我认为这是一个好主意

from __future__ import unicode_literals

在一些模块的顶部。换句话说,我是在自找麻烦(为了将来避免它们),但我可能在这里遗漏了一些重要的知识。我希望能够传递一个表示文件路径的字符串并像

一样简单地实例化一个对象

MyObject('H:\unittests')

Python 2.6 中,这工作得很好,不需要使用双反斜杠或原始字符串,即使对于以 '\u..' 开头的目录也是如此,这正是我想要的。在__init__ 方法中,我确保所有单个\ 出现都被解释为'\\',包括\a\b\b\n\r 等特殊字符之前的那些、\t\v(只有 \x 仍然是一个问题)。使用(本地)编码将给定的字符串解码为 un​​icode 也可以按预期工作。

Python 3.x 做准备,在编辑器中模拟我的实际问题(从 Python 2.6 中的干净控制台开始),发生以下情况:

>>> '\u'
'\\u'
>>> r'\u'
'\\u'

(到这里为止:'\u' 由控制台使用本地编码进行编码)

>>> from __future__ import unicode_literals
>>> '\u'
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 0-1: end of string in escape sequence

换句话说,(unicode) 字符串根本不会被解释为 unicode,也不会使用本地编码自动解码。即使对于原始字符串也是如此:

>>> r'\u'
SyntaxError: (unicode error) 'rawunicodeescape' codec can't decode bytes in position 0-1: truncated \uXXXX

u'\u' 也一样:

>>> u'\u'
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 0-1: end of string in escape sequence

另外,我希望isinstance(str(''), unicode) 返回True(它没有),因为导入 unicode_literals 应该使所有字符串类型都成为 unicode。 (编辑:) 因为in Python 3, all strings are sequences of Unicode characters,我希望str('')) 返回这样一个unicode 字符串,而type(str('')) 既是<type 'unicode'>,又是<type 'str'>(因为所有字符串都是unicode)但也意识到<type 'unicode'> is not <type 'str'>。周围一片混乱……

问题

  • 如何最好地传递包含“\u”的字符串? (不写'\\u')
  • from __future__ import unicode_literals 是否真的实现了所有 Python 3. 相关的 unicode 更改,以便获得完整的 Python 3 字符串环境?

编辑: 在 Python 3 中,<type 'str'> is a Unicode object<type 'unicode'> 根本不存在。就我而言,我想为 Python 2(.6) 编写可在 Python 3 中运行的代码。但是当我 import unicode_literals 时,我无法检查字符串是否为 <type 'unicode'>,因为:

  • 我假设 unicode 不是命名空间的一部分
  • 如果unicode 是命名空间的一部分,则<type 'str'> 在同一模块中创建时仍是unicode
  • 对于 Python 3 中的 unicode 文字,type(mystring) 将始终返回 <type 'str'>

我的模块过去常常通过顶部的# coding: UTF-8 注释以“utf-8”编码,而我的locale.getdefaultlocale()[1] 返回“cp1252”。因此,如果我从控制台调用 MyObject('çça'),它在 Python 2 中被编码为“cp1252”,在从模块调用 MyObject('çça') 时被编码为“utf-8”。在 Python 3 中,它不会被编码,而是一个 unicode 文字。

编辑:

我放弃了在u(或x)之前避免使用'\'的希望。我也了解导入unicode_literals 的局限性。但是,将字符串从模块传递到控制台的许多可能组合,反之亦然,每种不同的编码,除此之外是否导入unicode_literals 和 Python 2 与 Python 3,让我想通过以下方式创建一个概述实际测试。因此下表。

换句话说,type(str('')) 在 Python 3 中不返回 <type 'str'>,而是返回 <class 'str'>,所有 Python 2 的问题似乎都被避免了。

【问题讨论】:

  • 发现这很有帮助 blog:Ludovico Fischer 的 Python (2vs3) 中的字符串和 unicode

标签: python unicode future-proof


【解决方案1】:

AFAIK,from __future__ import unicode_literals 所做的只是将所有 字符串文字 设为 unicode 类型,而不是字符串类型。那就是:

>>> type('')
<type 'str'>
>>> from __future__ import unicode_literals
>>> type('')
<type 'unicode'>

但是strunicode 仍然是不同的类型,它们的行为和以前一样。

>>> type(str(''))
<type 'str'>

总是,是str 类型。

关于您的r'\u' 问题,这是设计使然,因为它相当于没有unicode_literals 的ru'\u'。来自文档:

当 'r' 或 'R' 前缀与 'u' 或 'U' 前缀一起使用时,将处理 \uXXXX 和 \UXXXXXXXX 转义序列,同时将所有其他反斜杠留在字符串中。

可能来自于词法分析器在 python2 系列中的工作方式。在 python3 中,它可以按照您(和我)的预期工作。

您可以输入两次反斜杠,然后\u 将不会被解释,但您会得到两个反斜杠!

反斜杠可以用前面的反斜杠转义;但是,两者都保留在字符串中

>>> ur'\\u'
u'\\\\u'

恕我直言,您有两个简单的选择:

  • 不要使用原始字符串,并转义反斜杠(与 python3 兼容):

    'H:\\unittests'

  • 过于聪明并利用 unicode 代码点(与 python3 兼容):

    r'H:\u005cunittests'

【讨论】:

  • In Python 3, all strings are sequences of Unicode characters。因此,如果type(str('')) 返回&lt;type 'str'&gt;,但str 对象是一个unicode,也应该等于&lt;type 'unicode'&gt;,当然,这不能同时为真。所以我很困惑......
  • 在puthon 3中所有的字符串都是Unicode字符的序列,所以只有一种类型的字符串,命名为str。在 python 2 中有两种类型的字符串:单字节字符串是str,Unicode 字符串是unicode。简单来说,Python2 unicode 等于 Python3 str,而 Python2 str 在 Python3 中不再存在(或者 bytes,如果你愿意,但这实际上不是字符串)。
  • 所以在 Python 3 中,type(str('')) 返回 &lt;type 'str'&gt;(表示 unicode),而在 Python 2 中,通过导入 unicode_literals,引入了新的字符串类型(unicode),但 &lt;type 'str'&gt;在 Python 2 上下文中仍然意味着&lt;type 'str'&gt;?这意味着 importing unicode_literals 的使用对于测试代码的未来证明非常有限,并且在迁移时仍然会遇到很多 unicode 问题...?
  • 没错。这就是为什么它被称为unicode_literals 而不是unicode_strings。只有字面意思改变;这是避免破坏向后兼容性所必需的。
  • 嗯,在 Python 2 中声明 r 表示带有未特殊处理的反斜杠的原始字符串是一个糟糕的决定,u 之前除外。 很高兴这已得到修复在 Python 3 中,但仍然……呃。
【解决方案2】:

对我来说,这个问题与版本不是最新的有关,在这种情况下是numpy

修复:

conda install -f numpy

【讨论】:

    【解决方案3】:

    我在 Python 3 上试试这个:

    导入操作系统

    os.path.abspath("yourPath")

    成功了!

    【讨论】:

      【解决方案4】:

      当您编写包含反斜杠的字符串文字时,例如路径(在 Windows 上)或正则表达式,请使用原始字符串。这就是他们的目的。

      【讨论】:

      • 不在此设置中。在from __future__ import unicode_literals 之后,您不能再对包含\u 的字符串使用原始字符串。
      猜你喜欢
      • 2016-11-03
      • 2021-05-17
      • 1970-01-01
      • 2018-04-11
      • 2016-01-04
      • 2022-11-02
      • 2010-11-23
      • 2023-02-22
      • 2016-09-20
      相关资源
      最近更新 更多