“u”和“r”string标记究竟做什么,以及什么是原始string文字?

当问这个问题时 ,我意识到我对原始string的了解不多。 对于自称是Django教练的人来说,这很糟糕。

我知道什么是编码,而且我知道自己得到什么是Unicode。

但是, r做了什么? 它会导致什么样的string?

而最重要的是,你到底做了什么?

最后,是否有任何可靠的方法从Unicodestring返回到一个简单的原始string?

嗯,顺便说一下,如果你的系统和你的文本编辑器字符集设置为UTF-8, u真的做了什么?

没有任何“原始string ”; 有原始的string文字 ,正是在开始引号之前用'r'标记的string文字。

一个“原始string文字”是一个string文字稍微不同的语法,其中一个反斜杠\ ,被认为是“只是一个反斜杠”(除非它正好在一个引号之前,否则会终止文字)没有“转义序列”来表示换行符,制表符,退格符,表单提要等等。 在正常的string文字中,每个反斜杠必须加倍以避免被当作转义序列的开始。

这种语法变体的存在主要是因为正则expression式模式的语法是反斜杠(但从来没有在最后,所以上面的“except”子句并不重要),而且当你避免每一个都加倍时, – 就这样。 它也得到了一些stream行的expression本地Windows文件path(反斜杠,而不是像其他平台上的正常斜线),但这是非常less需要的(因为正常的斜线大多在Windows上工作正常)和不完善(由于“except”子句以上)。

r'...'是一个字节string(在Python 2. *中), ur'...'是一个Unicodestring(同样在Python 2. *中),而其他三种引用中的任何一种相同types的string(例如r'...'r'''...'''r"..."r"""..."""都是字节串,如此)。

不确定“ 回头 ”是什么意思 – 没有内在的前后方向,因为没有原始的stringtypes ,它只是一个替代的语法来expression完全正常的string对象,字节或unicode,因为它们可能是。

是的,在Python 2. *中, u'...'当然总是不同于'...' – 前者是一个unicodestring,后者是一个字节string。 什么编码的文字可能会expression是一个完全正交的问题。

例如,考虑(Python 2.6):

 >>> sys.getsizeof('ciao') 28 >>> sys.getsizeof(u'ciao') 34 

Unicode对象当然需要更多的内存空间(对于一个非常短的string,显然是非常小的差异;-)。

Python中有两种types的string:传统的strtypes和较新的unicodetypes。 如果你在前面input一个没有u的string,你将得到一个存储8位字符的旧的strtypes,在前面你得到一个新的unicodetypes,它可以存储任何Unicode字符。

r根本不改变types,只是改变了string的解释方式。 没有r ,反斜杠被视为转义字符。 与r ,反斜杠被视为文字。 无论哪种方式,types是相同的。

ur当然是一个Unicodestring,其中反斜杠是文字反斜杠,而不是转义代码的一部分。

您可以尝试使用str()函数将Unicodestring转换为旧string,但是如果有任何unicode字符无法在旧string中表示,则会发生exception。 如果您愿意,可以先用问号replace它们,但当然这会导致这些字符不可读。 如果你想正确处理unicode字符,build议不要使用strtypes。

'原始string'意味着它被存储。 例如,'\'只是一个反斜杠而不是转义。

“u”前缀表示该值具有typesunicode而不是str

带有“r”前缀的原始string文字,转义其中的任何转义序列,因此len(r"\n")是2.因为它们转义转义序列,所以不能用一个反斜杠结束string文字:那不是有效的转义序列(例如r"\" )。

“原始”不是types的一部分,它只是表示价值的一种方式。 例如, "\\n"r"\n"是相同的值,就像0b1000000b100000是相同的。

你可以有unicode原始string文字:

 >>> u = ur"\n" >>> print type(u), len(u) <type 'unicode'> 2 

源文件编码只是决定如何解释源文件,否则不会影响expression式或types。 但是, build议避免使用ASCII以外的编码来改变含义的代码:

使用ASCII(或UTF-8,用于Python 3.0)的文件不应该有编码cookie。 只有当评论或文档string需要提及需要拉丁语-1的作者姓名时,才应使用Latin-1(或UTF-8); 否则,使用\ x,\ u或\ U转义是将非ASCII数据包含在string文本中的首选方式。

让我简单地解释一下:在Python 2中,可以将string存储为2种不同的types。

第一个是在Python中是strtypes的ASCII ,它使用1个字节的内存。 (256个字符,大部分会存储英文字母和简单符号)

第二种types是python中的unicodetypes的UNICODE ,它使用2个字节的内存。 (65536个字符,所以这包括地球上所有语言的所有字符)

默认情况下,python会更喜欢strtypes,但是如果你想以unicodetypes存储string,你可以把u放在文本前面,比如u'text',或者你可以通过调用unicode('text')来实现。

所以只是一个简单的方法来调用一个函数来投送到Unicode 。 而已!

现在r部分,你把它放在文本的前面告诉计算机,文本是原始文本,反斜杠不应该是一个逃避字符。 r'\ n'不会创build新的行字符。 这只是包含2个字符的纯文本。

如果你想将str转换为unicode,并且在那里放入原始文本,请使用ur,因为ru会引发错误。

现在,重要的部分:

你不能使用r来存储一个反斜杠,这是唯一的例外。 所以这段代码会产生错误: r'\'

要存储一个反斜杠(只有一个),你需要使用'\\'

如果你想存储超过1个字符,你仍然可以像r'\'那样使用r,如你所期望的那样会产生2个反斜杠。

我不知道r为什么不能在一个反斜杠存储中工作的原因,但是原因还没有被任何人描述。 我希望这是一个错误。

也许这是显而易见的,也许不是,但你可以通过调用x = chr(92)来创buildstring'\'

 x=chr(92) print type(x), len(x) # <type 'str'> 1 y='\\' print type(y), len(y) # <type 'str'> 1 x==y # True x is y # False