“u”和“r”字符串前缀具体有什么作用?什么是原始字符串字面量?
在问了这个问题后,我意识到自己对原始字符串的了解不多。作为一个自称是Django培训师的人,这真是太糟糕了。
我知道什么是编码,也知道u''
的作用,因为我明白Unicode是什么。
但是
r''
到底是干什么的呢?它会生成什么样的字符串?最重要的是,
ur''
又是什么鬼?最后,有没有可靠的方法可以把Unicode字符串转换回简单的原始字符串?
哦,对了,如果你的系统和文本编辑器的字符集设置为UTF-8,那么
u''
真的有用吗?
7 个回答
“原始字符串”的意思是它会按照显示的样子被存储。举个例子,'\'
就只是一个 反斜杠,而不是一个 转义字符。
在Python 2中,有两种字符串类型:传统的 str
类型和更新的 unicode
类型。如果你输入一个字符串时没有在前面加 u
,那么你得到的是旧的 str
类型,它只能存储8位字符;而如果在前面加上 u
,你就得到了更新的 unicode
类型,它可以存储任何Unicode字符。
这里的 r
并不会改变字符串的类型,它只是改变了字符串的解释方式。如果没有 r
,反斜杠会被当作转义字符来处理;而加上 r
后,反斜杠就会被当作普通字符来看待。无论如何,字符串的类型都是一样的。
ur
当然是一个Unicode字符串,其中的反斜杠是普通的反斜杠,而不是转义代码的一部分。
你可以尝试用 str()
函数把Unicode字符串转换成旧的字符串,但如果里面有任何不能用旧字符串表示的Unicode字符,你就会遇到错误。如果你愿意,可以先把这些字符替换成问号,但这样会导致这些字符变得不可读。如果你想正确处理Unicode字符,建议不要使用 str
类型。
其实没有什么“原始字符串”;只有“原始字符串字面量”,就是在开头加了一个'r'
的字符串。
所谓“原始字符串字面量”,是一种稍微不同的字符串写法。在这种写法中,反斜杠\
就表示“就是一个反斜杠”(除了在它后面跟着一个会结束字符串的引号时)——没有什么“转义序列”来表示换行、制表符、退格、分页等等。在普通字符串中,每个反斜杠必须写成两个反斜杠,以免被当成转义序列的开始。
这种语法的变化主要是因为正则表达式的模式中反斜杠用得很多(但它不会出现在最后,所以上面提到的“例外”就不重要了),这样写起来看起来更好看,不用每次都写两个反斜杠——就是这样。此外,它在表示Windows的文件路径时也变得有点流行(因为Windows用反斜杠,而其他平台用普通的斜杠),但这其实很少需要(因为普通斜杠在Windows上也大多数可以用)而且并不完美(因为上面提到的“例外”)。
r'...'
在Python 2.*中是字节字符串,ur'...'
是Unicode字符串(同样在Python 2.*中),其他三种引号的写法也会产生完全相同类型的字符串(比如r'...'
、r'''...'''
、r"..."
、r"""..."""
都是字节字符串,依此类推)。
不太明白你说的“回到后面”是什么意思——其实没有什么本质上的前后方向,因为没有原始字符串类型,它只是表达普通字符串对象的一种替代语法,无论是字节字符串还是Unicode字符串。
而且在Python 2.*中,u'...'
当然和'...'
是有区别的——前者是Unicode字符串,后者是字节字符串。字面量可能用什么编码表示是一个完全不同的问题。
例如,考虑(Python 2.6):
>>> sys.getsizeof('ciao')
28
>>> sys.getsizeof(u'ciao')
34
当然,Unicode对象会占用更多的内存空间(对于非常短的字符串来说,差别很小,显而易见;-)。