Python3编码问题(Python2请忽略)

一、python程序编辑界面和运行界面通常都是默认unicode编码字符串的,编辑界面则是ascii编码的,也就是程序语句是用ascii编码的。但最困扰编程小白的不在这里,请看二、

二、python的文本可以通过encode转化为字节流bytes,这时候困扰编程小白的问题来了。

(1)encode转化后的字节流bytes是不是字符串?

答:bytes不是字符串str。在python中,bytes是字节流bytes对象,字符串是字符串str对象。

(2)bytes不是字符串,那b'abc'怎么跟'abc'那么像?

答:这就不得不提一下坑爹的程序语言编写者们了,或者说console界面编写者们了。注意:在运行界面输出bytes时候,它是采取这样的原则的:每读一个字节就和ascii码比对一下,如果符合ascii码的可显示字符(特殊字符,字母和数字,控制字符除外),那这个字节就按照ascii码来表示,否则就按十六进制\x某某来表示。

>>> b'\x40\x41'

b'@A'

>>> b'\x00\x01'

b'\x00\x01'

这坑爹的原则不知道坑了多少迷糊的小白:怎么一会显示一个\xff,怎么一会又显示出一个a,而且看起来又是和字符串没啥区别,搞晕了。bytes对象的显示原则是这样,所以bytes对象不能包含超过0到127内ascii码范围的unicode字符串,而不能接受超过这个范围的unicode字符串。

>>> b'中'。

File "", line 1

SyntaxError: bytes can only contain ASCII literal characters.

(3)好啦,那在编辑界面怎么输入bytes?

答:直接用b'字符串'表示bytes对象,这时候相当于一个接受0到127内ascii码范围内的unicode码字符串的函数bytes(‘字符串’)。

>>> b'@&*hello'

b'@&*hello'

(4)好,如果我不用字符串表示bytes呢?又怎么搞?

答:直接用\x加两位十六进制数字表示一个字节就可以了。

>>> b'\x41\xff\x2e\97'

b'A\xff.\\97'

(5)字符串可以通过encode转化为bytes,bytes可以通过decode转化为字符串,问题又来了,不是学挖掘机哪家强,而是一个字符a有很多种编码的,按哪一种转化为bytes?bytes本身就是一串0和1的数字,按不同方式读可以解释成不同的字符,又怎么搞?

答:encode(‘编码方式’)时指定按那个编码转化为bytes。反之,decode(‘编码方式’)指定按那种方式读取字节码(0和1构成的数字流)。

>>> 'a'.encode('ascii')

b'a'

>>> 'a'.encode('utf-8')

b'a'

>>> 'a'.encode('gbk')

b'a'

>>> '中'.encode('gbk')

b'\xd6\xd0'

>>> '中'.encode('utf-8')

b'\xe4\xb8\xad'

(6)坑爹的问题又来了,python程序编辑界面的unicode码u'a'是字符串还是字节码?unicode码又怎么表示?

答:u'a'不是字节码,是字符串!坑爹啊!换句话说u'a'和'a'是一样一样的!坑爹啊!

>>> type(u'a')

<class 'str'>


unicode码再python里有两种表示方式:

u'字符串'或者'\u四位十六进制数'。它们是等价的,而且都是str对象。注意,'\\u四位十六进制数'与'\u四位十六进制数'并不相等,'\\u四位十六进制数'='\\’(斜杠本身是转义字符要经过转义表示)+'u四位十六进制数'。

>>> print('\u0065')

e

>>> print('\\u0065')

\u0065

(7)那如果它是字符串,我要转化为unicode码咋整?用encode指定unicode方式?

答:如果需要将内存用的unicode码直接保存,就指定编码方式是'unicode-escape'!

>>> '中'.encode('unicode')

Traceback (most recent call last):  File "", line 1, inLookupError: unknown encoding: unicode

>>> '中'.encode('unicode-escape')

b'\\u4e2d'

好!如果我不指定编码方式呢,又会怎么样?

encode默认编码方式是!!!utf-8!

>>> '中'.encode()

b'\xe4\xb8\xad'


三、python的py文件里指定编码方式,是指指定文件里所有内容都是按编码方式编码还是字符串按编码方式编码?

答:py文件的编码方式是ascii码,字符串默认编码是unicode码,指定编码方式是指定从硬盘读取py文件的编码方式。

实际上,要区分以下编码:系统默认编码(cmd,widows的txt文件),编辑界面编码(编辑界面显示文本的编码),运行界面编码(运行界面显示文本的编码),代码文件(py文件)编码,读入的文本编码,写出的文本编码。

(1)系统默认编码

以windows简体中文为例,系统默认编码是gbk,命令行输入chcp查看活动页代码为936。

如果将超出gbk范围的unicode码,写入系统的txt文件,报错!在cmd中print,报错!

处理方式:将unicode码encode为bytes再写入或print。

(2)编辑界面编码

编辑界面编码默认是ascii码,也就是写的程序语句默认是ascii编码,但一旦涉及到ascii码不能表示的,就隐形转换为系统默认编码表示,程序语句中的字符串默认是unicode码,也就是内存中的编码。

在py文件头声明文件的编码方式:

#-*- coding:utf-8 -*-

对编辑界面的字符串没有什么实质上的影响的!

pycharm编辑界面是默认utf-8的。所以有时在pycharm中编辑的代码中没有问题的字符串,放到cmd中编辑就会出现问题。设置在Editor->Code Style->File Ecoding->Project Ecoding。

(3)运行界面编码

cmd中运行程序,默认显示文本的编码是ascii码,一旦超出范围就隐式转换为系统编码。

在py文件头声明文件的编码方式:

#-*- coding:utf-8 -*-

对编辑界面和运行界面的字符串也没有什么实质上的影响的!坑爹啊!指定编码方式是告诉系统按照什么编码来读这个py文件的。

pycharm运行界面是默认utf-8的。所以有时在pycharm中没有问题的字符串,放到cmd中就会出现问题。所以有时在pycharm中print没有问题的字符串,放到cmd中print就会出现问题。设置在Editor->Code Style->File Ecoding->IDE Ecoding。

(4)代码文件编码

代码文件(py文件)本身也是一个文本,它也需要在硬盘或者其他载体上保存,默认编码是系统编码。这样的话,一旦py文件copy到不同平台,问题就会发生,出现乱码。

特别注意:

在py文件头声明文件的编码方式:

#-*- coding:utf-8 -*-

只是告诉python编译器在读取代码文件时按utf-8方式读取,但这个声明不能将py文件保存成utf-8格式的!

处理方式:

py文件要多平台运行,最好统一采用一个编码方式(如‘utf-8’)编辑和保存。

(5)读入文件编码

当从网络或者硬盘读入文件的时候,实质上读到的是字节流:

硬盘读入文件的默认编码方式是系统编码方式,当出现超过gbk范围的字节出现,报错!

网络读入文件时,因为读入的是字节,不会报错,但一旦要print时就会报错!

所以,如果不能按照读入文本的编码方式转化为unicode,就会出现问题。

处理方式:

因为read()没有编码方式参数,只能读入bytes然后在解码为unicode码或者其他编码。

判断读入内容的编码方式可以用chardet的detect方法,接受一段bytes参数,返回一个结果的字典,里面包含编码方式和信度区间。

withopen('/Users/liaorikun/Desktop/gbktest.txt','rb')asf:

s = f.read()

chatest = chardet.detect(s)

# print(s)

print(chatest)

检测结果:

{'encoding': 'GB2312', 'confidence': 0.99}

(6)写出文件编码

写文件编码参看(1)

如果想将文本直接以unicode码保存到文件,用encode(‘unicode-escape’)转化为bytes,写入文件。

如果想将文本以utf-8形式保存到文件,用encode(‘utf-8’)转化为utf-8编码的bytes,写入文件。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,319评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,801评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,567评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,156评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,019评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,090评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,500评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,192评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,474评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,566评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,338评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,212评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,572评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,890评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,169评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,478评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,661评论 2 335

推荐阅读更多精彩内容