关于python utf 8编码编码,你真的明白了吗

关于python的编码_python吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:185,023贴子:
关于python的编码收藏
今天研究了好一会,上网看了一堆文章,最后还是自己试明白的。当你读取一个文件时,你必须知道这个文件本身的编码,比如是gb1830,那么在代码里用.decode(&gb1830&)才能正确解码,把它变成unicode字符串问题就是常常不知道,这时候我用的办法就是,把那个文件另存为一个知道的编码
啦啦啦,啦啦啦,我是顶楼的小行家,三,花,聚,顶,我顶…
在pypi上搜索chardet,这个模块用于检测文本的编码
好办法,不过我很少碰到编码难解决的问题了
登录百度帐号人生苦短,我用Python投稿:225粉丝:3634分享--dynmicweibozoneqqbaidu将视频贴到博客或论坛视频地址复制嵌入代码复制微信扫一扫分享收藏0硬币--稍后看马克一下~用手机看转移阵地~用或其他应用扫描二维码手机下视频请使用扫码若未安装客户端,可直接扫此码下载应用未经作者授权 禁止转载
看过该视频的还喜欢正在加载...miniOFF后使用快捷导航没有帐号?
只需一步,快速开始
请完成以下验证码
请完成以下验证码
主题帖子荣誉
查看: 12530|回复: 62
& 累计签到:2408 天连续签到:7 天
马上注册加入鱼C,享用更多服务吧^_^
才可以下载或查看,没有帐号?
初学 Python,相信大家遇到的一大难题就是编码问题,如下:
Traceback (most recent call last):
&&File &/Users/FishC/Documents/Python/test.py&, line 2, in &module&
& & print(f1.read())
&&File &/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/encodings/ascii.py&, line 26, in decode
& & return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xce in position 0: ordinal not in range(128)
复制代码
这样的报错信息着实令大家很头疼,因为在网上很难找到解决方案。
这里小甲鱼给大家总结一下几种会导致编码问题的案例,并逐一解释......
案例一:中文输出是乱码?
# Python 版本:2.7.6
&&& string1 = &我爱鱼C工作室&
&&& string1
'\xe6\x88\x91\xe7\x88\xb1\xe9\xb1\xbcC\xe5\xb7\xa5\xe4\xbd\x9c\xe5\xae\xa4'
&&& print string1
我爱鱼C工作室
&&& string2 = &I love FishC&
&&& string2
'I love FishC'
复制代码
问:为何无法直接显示中文的字符串?
因为 Python2.x 的版本默认的编码是 ASCII,ASCII 默认只用一个字节来存放数据。由于中国汉字博大精深,一个字节是不足以存放所有的汉字的。因此,string1 只能打印出中文字符串在内存中的数据,这并不是错误。
解决方案:
使用 Python3,因为 Python3 默认使用 UTF-8 编码。
延伸知识:
1. 可以用以下方法获得当前的默认编码:
&&& import sys
&&& sys.getdefaultencoding()
'ascii'
复制代码
案例二:普通字符串和 Unicode 字符串进行拼接抛出 UnicodeDecodeError 异常
&&& string = &我爱& + u&FishC&
Traceback (most recent call last):
&&File &&stdin&&, line 1, in &module&
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 0: ordinal not in range(128)
复制代码
使用 + 号进行字符串拼接,左边是普通字符串,右边是 Unicode 字符串。当两种类型的字符串拼接的时候,Python 会自动将左边的中文字符串转换为 Unicode 字符串,再进行拼接操作。但由于 &我爱& 的 ASCII 编码为 '\xe6\x88\x91\xe7\x88\xb1',其中十六进制 '\xe6' 对应的值是 230。当编码值在 0 ~ 127 的时候,Unicode 和 ASCII 是兼容的,转换不会有什么问题。但当值大于 128 的时候,ASCII 编码便不能直接转换为 Unicode 了。因此,抛出 UnicodeDecodeError。
解决方案:
1. 使用 Python3
2. 指定转换为 Unicode 的解码方式:
&&& string = &我爱&.decode('utf-8') + u&FishC&
&&& print string
我爱FishC
复制代码
3. 将 Unicode 字符串部分进行编码:
&&& string = &我爱& + u&FishC&.encode(&utf-8&)
&&& print string
我爱FishC
复制代码
延伸知识:
Unicode 编码系统的发明是为了统一各国文字的编码,因此把它称为万国码。Unicode 为每种语言设置了唯一的二进制编码表示方式,也就是说无论哪个国家的语言,都可以在 Unicode 上找到对应的代码。因此,当不同的编码系统进行相互转换的时候,可以利用 Unicode 做一个“中介”。
其他编码系统到 Unicode 的转换过程我们称为解码(decode),将 Unicode 转换为其他编码系统的过程称之为编码(encode)。例如 A 编码需要转换为 B 编码,过程如下:
A编码 -& decode(A) -& Unicode -& encode(B) -& B 编码
案例三:文件编码与 Python 编码不同
test.txt 内容如下,并保存为 GB2312 编码:
我爱鱼C工作室,真的!
复制代码
test.py 内容如下:
f1 = open(&test.txt&)
print(f1.read())
f1.close
复制代码
代码执行后会报错:
&&&
Traceback (most recent call last):
&&File &/Users/FishC/Documents/Python/test.py&, line 4, in &module&
& & print(f1.read())
&&File &/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/encodings/ascii.py&, line 26, in decode
& & return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xce in position 0: ordinal not in range(128)
复制代码
如果前边的内容都可以理解了,那么解决这样的编码问题就不再难得住你啦~~~
使用 open 打开文件的编码格式取决于系统(可以通过 locale.getpreferredencoding() 获得),认真看报错信息,这里系统使用 ASCII 对文件内容进行解码,遇到错误......因为我们知道文件的存放格式是 GB2312,因此我们只需要在打开文件的时候设置 encoding=&gb2312& 即可解决问题:
f1 = open(&test.txt&, encoding=&gb2312&)
print(f1.read())
f1.close
复制代码
希望起到一个抛砖引玉的作用,有关 Python 的编码问题,大家可以在这个帖子继续展开讨论~
如果本文对你有帮助,可以通过【评分】功能加分鼓励哦^_^
看懂了,赞!
感谢楼主无私奉献!
感谢楼主无私奉献!
支持楼主!
好帖子,看得太明白了
没有完全看懂,但是知道学习的方向了
感谢感谢,还好我没放弃!
小甲鱼老师太万能啦!
支持楼主!
本帖被以下淘专辑推荐:
& |主题: 8, 订阅: 13
& |主题: 24, 订阅: 13
& |主题: 20, 订阅: 11
& |主题: 11, 订阅: 5
& |主题: 1, 订阅: 0
& 累计签到:532 天连续签到:1 天
终于发现了装不上3.x以下的好处了,不用担心打印的编码问题了。。
& 累计签到:378 天连续签到:1 天
& 累计签到:4 天连续签到:1 天
感谢楼主啊~~~
& 累计签到:333 天连续签到:1 天
& 累计签到:68 天连续签到:1 天
& 尚未签到
:lol::lol::lol::lol:
& 累计签到:14 天连续签到:1 天
起先用的是 2.7, 编码问题纠结了足有3天,折腾了3天之后貌似有点头绪(windows),现在忘了,后来一看python3 无压力,就果断换3了, 用着舒心啊。。。
& 累计签到:48 天连续签到:1 天
非常感谢!
& 累计签到:548 天连续签到:1 天
& 累计签到:30 天连续签到:1 天
又学到了 支持
& 累计签到:1420 天连续签到:70 天
& 累计签到:38 天连续签到:1 天
非常感谢!~~
& 累计签到:2 天连续签到:1 天
谢谢分享方案
& 累计签到:40 天连续签到:1 天
优秀!!!!!!!!!!!!!!!!!!
& 累计签到:129 天连续签到:1 天
看一些其他资料介绍,现在的Python3.X开始用字符串类型(str)来代替Unicode类型了,省去了不少编码问题:lol:
& 累计签到:35 天连续签到:1 天
本帖最后由 jeffery_xu82 于
23:57 编辑
学习中。谢谢。
& 累计签到:1 天连续签到:1 天
& 累计签到:4 天连续签到:1 天
又长知识了,谢谢楼主
& 累计签到:39 天连续签到:1 天
小甲鱼强烈推荐
新的视频新的面貌,希望大家喜欢 (≧∇≦)ノ
- - - - - - - - - - - -
新课程,新体验!
移动客户端下载(未启用)
微信公众号
Powered by
Copyright &
&&& All Rights Reserved.python中理解字符串和编码为什么这么难 - 简书
python中理解字符串和编码为什么这么难
在学习python2的时候,字符串和编码可以说是最让人困惑的知识点,假如知其然而不知其所以然,则在后续的写代码和学习过程中会让人很痛苦,甚至会放弃,而对比PHP语言来说,即使完全不了解编码等知识,也可以写出代码,这是幸事,但反过来说太透明会让你失去很多能力.
python2字符串和编码难理解的原因在于,一方面很多书籍很少说这方面的知识,另外一方面是python设计导致的,编码问题和文件编码,系统环境,IO操作等都有关系,混杂在一块很让人头疼.
网络上也有很多中文资料去说明,但是在学习的时候只能借鉴,原因在于写的人理解的也是比较片面,很容易误导人,所以在学习过程中一定要去实践,要仔细琢磨.
自己综合学习了下,以自己的方式写了篇博客,能力有限,希望不要误导人.
对于编码个人觉得理解概念即可,具体的转换规则,存储规则可以不用太仔细了解,这类似于进制,知道概念即可,不强制掌握进制转换的方法.
讲编码的文章很多,掌握以下概念即可.
世界上任何一个字符都可以用一个Unicode编码来表示,一旦字符的Unicode编码确定下来后,就不会再改变了,但是unicode存在二个局限性,第一一个Unicode字符在网络上传输或者最终存储起来的时候,并不见得每个字符都需要两个字节,所以可能会造成空间浪费,第二一个Unicode字符保存到计算机里面时就是一串01数字,那么计算机怎么知道一个2字节的Unicode字符是表示一个2字节的字符呢,还是表示两个1字节的字符呢.
Unicode只是规定如何编码,并没有规定如何传输、保存这个编码.
例如“汉”字的Unicode编码是6C49,可以用4个ascii数字来传输、保存这个编码,也可以用utf-8编码的3个连续的字节E6 B1 89来表示它,关键在于通信双方都要认可.
因此Unicode编码有不同的实现方式,比如:UTF-8、UTF-16等等
python下的编码
python2对于编码理解困难,很大一部分原因在于系统有很多编码,这里说明下
#windows环境和linux环境下的区别
sys.getdefaultencoding()
sys.getfilesystemencoding()
locale.getdefaultlocale()
locale.getpreferredencoding()
sys.stdout.encoding()
sys.getdefaultencoding()不管在何种环境下返回都是ascii,所以默认情况下转码解码默认都是ascii
对于str类型,locale.getdefaultlocale()决定了具体的编码格式.具体见下面说明
sys.stdout.encoding表示输出使用的编码,同样的文件编码,同样的代码,不同的系统环境输出是有差异的
文件本身的编码和文件头编码(# coding=utf-8)保持一致
Python2中str和unicode对象
首先声明下,自己运行的代码在windows和linux环境各有一份示例,且通过python交互式解析器来说明.
python解析器不用用户定义编码头,所以内部处理依赖于locale环境.
在windows机器运行
&&& import locale
&&& locale.getdefaultlocale()
('zh_CN', 'cp936')
在linux机器运行
&&& import locale
&&& locale.getdefaultlocale()
('en_US', 'UTF-8')
在python中和字符串相关的数据类型,分别是str、unicode两种,他们都是basestring的子类.
在python代码中定义str,unicode类型,解析器是如何解析的呢
读出文件内容
将内容根据文件编码解码成为unicode
解析unicode字符串,假如定义是u开头,创建一个unicode对象
解析str字符串,将会从unicode按照文件编码再编码成为str对象
通过代码看看字符串在内部是如何存储的
&&& a="哈哈"
&&& type(a)
&type 'str'&
'\xb9\xfe\xb9\xfe'
&&& len(a)
&&& a = '哈哈'
&&& type(a)
&type 'str'&
'\xe5\x93\x88\xe5\x93\x88'
&&& len(a)
str存储的是已经编码后的字节序列,输出时看到每个字节用16进制表示,以\x开头,
linux环境下每个汉字会占用3个字节的长度,windows环境下每个汉字会占用2个字节的长度
unicode类型
#linux和windows环境一样
&&& a=u'哈哈'
&&& type(a)
&type 'unicode'&
u'\u54c8\u54c8'
&&& len(a)
unicode是"字符"串,存储的是编码前的字符,输出是看到字符以\u开头,每个汉字占用一个长度
通过上述可以看出:
定义unicode和系统环境没有联系,存储的是以u开头的unicode字符集
str类似于字符数组,str类型定义内部存储则和系统环境有关系,假如系统环境是utf-8则存储utf-8规则的字符数组,假如系统环境是cp936则存储cp936规则的字符数组.
str类型不要使用len这样的函数,因为截取出来可能就是所谓的乱码了.
python2中str和unicode如何转换
既然同时存在str和unicode类型,则就涉及到二者的转换了.
先说基本概念
str = unicode.encode(字符编码),从unicode转换成指定编码的str对象
unicode = str.decode(字符编码),特指从指定编码的str对象转换为unicode对象
str转换为unicode的时候,必须知道原有字符串编码是什么类型的,假如指定错误则会报错
str从一种编码转换为另外一种编码的时候,必须先转换为unicode,再转换成指定编码的str类型
一般情况下,不应该同时定义str和unicode类型,尽量使用unicode类型,假如都统一使用unicode类型,那为什么还要出现str类型呢,在python2中,一般在I/O操作的时候才会有编码转换,这在后面描述.
print字符串发生了什么
任何对象都默认包含内建方法str,在print的时候,该方法生效
假如print unicode对象,则根据默认编码解码为str对象.
假如print str对象,由于输出就是str对象,默认不用做任何解码.
看下面的例子,注意这里是通过python file.py的方式运行,在windows下运行是乱码,而在linux下运行显示正确,原因在于sys.stdout.encoding
#!/usr/bin/env python
#coding=utf-8
a = '哈哈'
sys.stdout.encoding表示print输出使用的编码.
在linux环境下,由于输出的编码本来就是utf-8,所以能正确显示
在windows环境下,str字符串存储的是utf-8序列,显示要求的却是gbk,则出现乱码,所以需要转码,修改如下:
#!/usr/bin/env python
#coding=utf-8
a = '哈哈'
print a.decode('utf-8').encode('gbk')
#在内部存储gbk类型的str字符串
而定义uinicode对象的时候,不会涉及任何的转码问题,print的时候,unicode对象能够根据文件编码自动转换
以下代码在任何环境下都能正常运行
#!/usr/bin/env python
#coding=utf-8
a = u'哈哈'
IO操作发生了什么
正因为有IO操作,str类型的对象可能才有存在的意义.或者说假如没有可恶的str对象,则世界就太平了.
内置的open函数打开文件时,read方法读取的是一个str,用你知道的编码把它解码成unicode
open函数打开文件之后的写操作,则需要将需要写入的字符串按照其编码encode为一个str.
是不是很熟悉,print语句输出和文件打开一样都是str类型,尽可能处理的时候抛弃str,确保处理的对象是unicode,只在需要的时候才转码.
通过下面的代码就能明白繁琐的转码和解码操作
#!/usr/bin/env python
#coding=utf-8
def filewrite():
file1 = os.getcwd() + "\1.txt"
file2 = os.getcwd() + "\2.txt"
str= u'我们是中国人'
f = open(file1, "a")
f.write(str.encode('gbk'))
f2 = open(file2, "a")
f2.write(str.encode('utf-8'))
f2.close()
def fileread():
file1 = os.getcwd() + "\1.txt"
file2 = os.getcwd() + "\2.txt"
f= open(file1,"r")
data = f.read()
print(data)
f= open(file2,"r")
data = f.read()
print(data.decode('utf-8'))
filewrite()
fileread()
IO操作使用codecs
codecs模块也提供了一个open函数,可以直接指定好编码打开一个文本文件,那读取到的文件内容则直接是一个unicode字符串.对应的指定编码后的写入文件,则可以直接将unicode写到文件中
#!/usr/bin/env python
#coding=utf-8
import codecs
def codecswrite() :
file3 = os.getcwd() + "\3.txt"
str = u'哈哈'
f = codecs.open(file3,"w",'utf-8')
f.write(str)
def codecsread():
file3 = os.getcwd() + "\3.txt"
f = codecs.open(file3,"r",'utf-8')
data = f.read()
print (data)
codecswrite()
codecsread()
字符串拼接发生了什么
unicode和str类型通过+拼接时,输出结果是unicode类型,相当于先将str类型的字符串通过decode()方法解码成unicode再拼接
#windows环境,python交互式运行
&&&a="中国"
&&&b=u"你好"
会出现UnicodeDecodeError: 'ascii' codec can't decode byte 0xd6 in position 0: ordinal not in range(128)错误,原因在于python自动将str类型的变量按照默认的编码格式sys.getdefaultencoding()来解码,默认编码即ascii,而这个字符不在ascii的范围内,就出现了错误,所以需要修改如下
#windows环境,python交互式运行
&&&a="中国"
&&&b=u"你好"
&&& a.decode('gbk')+b
u'\u4e2d\u56fd\u4f60\u597d'
让我们轻松下
这里看下python中的字符串的处理方式,其实在学习的时候和PHP比较下更让人有印象
单引号,双引号,转义
python中,字符串可以用单引号和双引号括起来,没有区别.
假如字符串用单引号括起来,则字符串中则不能有单引号,除非通过转义去处理,同理双引号也一样
&&& "hello"
&&& print "hello"
通过python打印的字符串会被双引号括起来,这是因为python打印值的时候会保持该值在python代码中的状态.
而通过python语句则结果不一样.
这里就涉及到值被转换为字符串的两种机制:
str函数:把值转换为合理形式的字符串,以便人类能够理解.
repr函数:把值转换为python能够认识的值.
&&& print repr("hello")
&&& print repr(1000L)
&&& print str("hello")
&&& print str(1000L)
input和raw_input
input假设输入的是合法的python表达式,不然会报错
&&& name=input("please:")
please:hello
Traceback (most recent call last):
File "&stdin&", line 1, in &module&
File "&string&", line 1, in &module&
NameError: name 'hello' is not defined
应该变更为:
&&& name=input("please:")
please:"hello"
&&& print name
而raw_input函数则将所有的输入当作原始数据
&&& name=raw_input("please:")
please:hello
&&& print name
假如要写多行的字符可以使用三个引号
str='''hello
print(str)
引号之间的内容原本是什么样输出也是什么样的,可以直接使用单双引号,不用转义
普通字符也可以跨行,只要一行之中最后一个字符是反斜线,那么换行就转义了
str='hello\
print(str)
原始字符串
原始字符串对于反斜线不会特殊对待
str=r'hello\nworld'
print(str)
\n字符在原始字符串里面就不是换行了而是原始的\n字符
PHP Python 程序员 微信公众号(yudadanwx)
字符集和编码简介 在编程中常常可以见到各种字符集和编码,包括ASCII,MBCS,Unicode等字符集。确切的说,其实字符集和编码是两个不同的概念,只是有些地方有重合罢了。对于ASCII,MBCS等字符集,基本上一个字符集方案只采用一种编码方案,而对于Unicode,字符...
http://python.jobbole.com/85231/ 关于专业技能写完项目接着写写一名3年工作经验的Java程序员应该具备的技能,这可能是Java程序员们比较关心的内容。我这里要说明一下,以下列举的内容不是都要会的东西—-但是如果你掌握得越多,最终能得到的评价、...
本文转自:http://www.crifan.com/crifan_released_all/books/ Python 2.x中的字符编码,设计的的确不好,导致初学者,甚至是即使用Python很长时间的人,都会经常遇到字符编解码方面的错误。 下面就把一些常见情,尽量的都整...
Python黑帽编程2.3字符串、列表、元组、字典和集合 本节要介绍的是Python里面常用的几种数据结构。通常情况下,声明一个变量只保存一个值是远远不够的,我们需要将一组或多组数据进行存储、查询、排序等操作,本节介绍的Python内置的数据结构可以满足大多数情况下的需求。...
本节要介绍的是Python里面常用的几种数据结构。通常情况下,声明一个变量只保存一个值是远远不够的,我们需要将一组或多组数据进行存储、查询、排序等操作,本节介绍的Python内置的数据结构可以满足大多数情况下的需求。这一部分的知识点比较多,而且较为零散,需要认真学习。 2....
降温了。 窗外的雨,淅淅沥沥地落了下来,漫山遍野笼罩在轻纱样的雨雾里。我收紧衣服,匆匆拿起沙发上的围巾,出门上班去。走在雨中,望着来来往往的路人,他们中有一部分跟我一样戴着围巾,五颜六色,有手织的,有商店里买的。每天我都会路过一个小学,那些天真可爱的孩子,笑着,闹着,乐开了...
好的时候是真好 以后想回去 也回不去了
喜欢莺歌海是因为它让我在海南的生活有了憧憬。 上一次去海边已经是很久以前了,我对于海的渴望很深,但到了海边之后,很快也会感觉到没有终点的苦闷。浪打上来退下去,一点也不会累,于是我就累了。 那个时候,我总会想到莺歌海。 莺歌海是乐东附近的一个盐场,已经离开了景区,包围在老旧的...
一个多月前,在某宝买了双鞋,说实在的,不贵,几十块钱,但是对于一个还在跟家里要生活费的学生来说,这些钱也不算少,两三天的生活费。用户体验并不好,底子很薄,穿着有点硌脚,鞋子两只的颜色都不一样,买的白色,但有一只是有点发黄的。联系了客服,说让我找售后,之后就无论说什么都...
莫问前程 净空灵魂
庄严言行 1:每天早上醒来第一件事情,给浙江法幢寺日行一善捐款,给藏经阁日行一善捐款,给慈济慈善基金会日行一善捐款,供养三宝,种下慈悲,智慧,财富的福田。 2:.每天听种子法则讲座并分享与更多的人了解收益种子智慧,...没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!

我要回帖

更多关于 python 编码 的文章

 

随机推荐