(unicode错误)'unicodeescape'编解码器无法解码字节 - 字符串带'\ u'

Rem*_*emi 24 python unicode future-proof

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

from __future__ import unicode_literals
Run Code Online (Sandbox Code Playgroud)

在一些模块的顶部.换句话说,我要求麻烦(将来要避免它们),但我可能会遗漏一些重要的知识.我希望能够传递表示文件路径的字符串并实例化一个简单的对象

MyObject('H:\unittests')

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

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

>>> '\u'
'\\u'
>>> r'\u'
'\\u'
Run Code Online (Sandbox Code Playgroud)

(好到这里:'\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
Run Code Online (Sandbox Code Playgroud)

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

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

同样的 u'\u':

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

此外,我希望isinstance(str(''), unicode)返回True(它没有),因为导入unicode_literals应该使所有字符串类型unicode.(编辑:)因为在Python 3中,所有字符串都是Unicode字符的序列,我希望str(''))返回这样的unicode-string,并且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'>是一个Unicode对象,<type 'unicode'>根本就不存在.在我的情况下,我想编写Python 2(.6)的代码,它将在Python 3中运行.但是当我import unicode_literals,我无法检查字符串是否是<type 'unicode'>因为:

  • 我假设unicode不是命名空间的一部分
  • if unicode是命名空间的一部分,<type 'str'>当在同一模块中创建时,文字仍然是unicode
  • type(mystring)将永远返回<type 'str'>Python 3中的unicode文字

我的模块使用# 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(''))不会<type 'str'>在Python 3中返回,但是<class 'str'>,似乎可以避免所有Python 2问题.

rod*_*igo 18

AFAIK,from __future__ import unicode_literals所做的就是使所有字符串文字都是unicode类型,而不是字符串类型.那是:

>>> type('')
<type 'str'>
>>> from __future__ import unicode_literals
>>> type('')
<type 'unicode'>
Run Code Online (Sandbox Code Playgroud)

strunicode仍然不同类型,他们的行为就像以前一样.

>>> type(str(''))
<type 'str'>
Run Code Online (Sandbox Code Playgroud)

总是,属于str类型.

关于你的r'\u'问题,它是设计的,因为它相当于ru'\ u'没有unicode_literals.来自文档:

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

可能来自词法分析器在python2系列中的工作方式.在python3中它可以像你(和我)所期望的那样工作.

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

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

>>> ur'\\u'
u'\\\\u'
Run Code Online (Sandbox Code Playgroud)

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

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

    'H:\\unittests'

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

    r'H:\u005cunittests'