python字符串前缀与字符编码设置的使用小技巧
这一周事情有点多。(开学后这段时间的摆烂造成了严重后果,组会后的心情十分低落。)
周末没有抽出太多时间探索新的知识,谨在此po一篇去年整理的旧文。
一、python字符串前缀使用小技巧
1、字符串前加u
例子: u"字符串中有中文"
含义:
前缀u表示该字符串是unicode编码,主要用于在Python2中,用在含有中文字符的字符串前,防止因为编码问题,导致中文出现乱码,另外一般要在文件开关标明编码方式采用utf8( #coding=utf-8
)。
由于在Python3中,所有字符串默认都是unicode字符串,这一前缀也就失去了作用。现在我们编写python代码基本用不上这个前缀了,但有时候翻看前人发表的模型或软件,偶尔可能会碰上。
1 | str1 = u"字符串中有中文" |
2、字符串前加r
例子: r"\n\t"
含义:
在普通字符串中,反斜线是转义符,代表一些特殊的内容,如换行符\n
。前缀r表示该字符串是原始字符串,即\
不是转义符,只是单纯的一个符号。常用于特殊的字符如换行符、正则表达式、文件路径。
注意不能在原始字符串结尾输入反斜线,否则Python不知道这是一个字符还是换行符(字符串最后用\
表示换行),会报错:
1 | >>> str21 = r'C:\Program File\my\path\' |
如果一个字符串确实是以\
结尾(如文件夹路径),可以再接一个转义\
的字符串以规避上面的报错。
1 | str21 = r'C:\Program File\my\path''\\' |
3、字符串前加b
例子: b'<h1>Hello World!</h1>'
含义:
前缀b表示该字符串是bytes类型。主要用在Python3中,因为Python3里默认的str是unicode类。Python2的str本身就是bytes类,所以可不用。
常用在如网络编程中,服务器和浏览器只认bytes类型数据。
如:send 函数的参数和 recv 函数的返回值都是bytes类型。
在Python3中,bytes和str的互相转换方式是
1 | str.encode('utf-8') # str转为bytes |
示例:
1 | str3 = b'<h1>Hello World!</h1>' |
4、字符串前加f
例子:
1 | >>> name = 'python' |
含义:
前缀f
是python3.6新加特性,用来格式化字符串。可以看出f
前缀可以更方便的格式化字符串, 比format()
方法可读性高且使用方便。而且加上f
前缀后, 支持在大括号内, 运行Python表达式。你还可以用fr前缀来表示原生字符串。
1 | code_name = 'python' |
二、python在使用open()
读取文件时的字符串编码问题
在windows平台下使用python内置函数 open() 时发现,当不传递encoding参数时,会自动采用gbk(cp936)编码打开文件,而当下很大部分文件的编码都是UTF-8,因此可能会出现文件打开失败的情况。
我们当然可以通过每次给open()
函数手动传参encoding='utf-8'
,但是略显冗余,而且有很多外国的第三方包,里面调用的内置open()
函数并没有提供接口让我们指定encoding,这就会导致这些包在windows平台上使用时,常会出现如 "UnicodeDecodeError: 'gbk' codec can't decode byte 0x91 in position 209: illegal multibyte sequence"
的报错
通过查看python文档分析原因:
if encoding is not specified the encoding used is platform dependent: locale.getpreferredencoding(False) is called to get the current locale encoding. (For reading and writing raw bytes use binary mode and leave encoding unspecified.)
可以发现当open()
不传递encoding参数时,是默认调用locale.getpreferredencoding()
方法来获取当前平台的“默认编码类型”,继续查看相关文档,发现有两种方法可以指定windows平台下Python运行时的“默认编码类型”。
1. 指定sys.flags.utf8_mode
通过运行python脚本时添加命令行参数 -X utf8
(注意是跟在python.exe后面的interpreter option,不是跟在要运行脚本后面的parameters!)
指定sys.flags.utf8_mode
参数之后,Python运行时会在很多场景下自动使用utf-8编码,而不是win默认的gbk(cp936)编码。
2. 直接重写_locale
1 | import _locale |
python解释器会取_getdefaultlocale()[1]
作为默认编码类型,重写后,会改变当前运行环境下的所有模块的默认编码。
如果在windows下, 还可以在Python安装目录下的Lib/site-packages
目录中,新建一个sitecustomize.py
文件:
1 | import _locale |
这样,可以让locale设置在每次python启动时都生效。
总之,使用以上两种方法后,windows平台下,open()
函数会默认用utf-8编码打开文件。其实不止open()
方法,跨模块、全局改变python解释器的默认编码为utf-8,会带来很多使用上的便利,而不需要被gbk编码报错的噩梦所纠缠。