python中的编解码小结
在用python27写文件或者上传文件时遇到这样一个问题:。在网上搜了下说加入以下三行代码可以解决:
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
试了一下果然解决问题。
总结一下原理:
Python 里面的编码和解码也就是 unicode 和 str 这两种形式的相互转化。编码是 unicode -> str,相反的,解码就是 str -> unicode。剩下的问题就是确定何时需要进行编码或者解码了.关于文件开头的"编码指示",也就是 # -*- coding: -*- 这个语句。Python 默认脚本文件都是 UTF-8 编码的,当文件中有非 UTF-8 编码范围内的字符的时候就要使用"编码指示"来修正. 关于 sys.defaultencoding,这个在解码没有明确指明解码方式的时候使用。比如我有如下代码:
#! /usr/bin/env python
# -*- coding: utf-8 -*-
s = '中文' # 注意这里的 str 是 str 类型的,而不是 unicode
s.encode('gb18030')
这句代码将 s 重新编码为 gb18030 的格式,即进行 unicode -> str 的转换。因为 s 本身就是 str 类型的,因此 Python 会自动的先将 s 解码为 unicode ,然后再编码成 gb18030。因为解码是python自动进行的,我们没有指明解码方式,python 就会使用 sys.defaultencoding 指明的方式来解码。很多情况下 sys.defaultencoding 是 ANSCII,如果 s 不是这个类型就会出错。拿上面的情况来说,我的 sys.defaultencoding 是 anscii,而 s 的编码方式和文件的编码方式一致,是 utf8 的,所以出错了: UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128) 。
对于这种情况,我们有两种方法来改正错误:
一是明确的指示出 s 的编码方式:
#! /usr/bin/env python
# -*- coding: utf-8 -*- s = '中文'
s.decode('utf-8').encode('gb18030')
二是更改 sys.defaultencoding 为文件的编码方式
#! /usr/bin/env python
# -*- coding: utf-8 -*- import sys
reload(sys) # Python2.5 初始化后会删除 sys.setdefaultencoding 这个方法,我们需要重新载入
sys.setdefaultencoding('utf-8') str = '中文'
str.encode('gb18030')
但是!用sys.setdefaultencoding('utf-8')这种方式有时候会遇到很奇怪的bug。问题不在描述了,都是血泪。
所以再遇到UnicodeEncodeError: 'ascii' codec can't encode characters in position 10-13: ordinal not in range(128)时,一律明确的指示出编码方式。
比如在读写文件时,需要先将读出的文本decode成需要的文本,写文件时,需要encode成字节再写入。
file_object = open(read_file, 'r')
conf_object = open(write_file, 'w')
try:
all_text = file_object.read()
all_text = all_text.decode('utf-8')
all_text = all_text.replace('aa', 'bb')
all_text = all_text.encode('utf-8')
conf_object.write(all_text)
except:
print "read or write failed"
几个建议:
- 当取回来的数据与你当前脚本中声明的编码不一致时就要做编码转换。
- 所有 text string 都应该是 unicode 类型,而不是 str,如果你在操作 text,而类型却是 str,那就是在制造 bug。
- 在需要转换的时候,显式转换。从字节解码成文本,用
var.decode(encoding)
,从文本编码成字节,用var.encode(encoding)
。 - 从外部读取数据时,默认它是字节,然后
decode
成需要的文本;同样的,当需要向外部发送文本时,encode
成字节再发送
python中的编解码小结的更多相关文章
- Java 字符编码(二)Java 中的编解码
Java 字符编码(二)Java 中的编解码 java.nio.charset 包中提供了一套处理字符编码的工具类,主要有 Charset.CharsetDecoder.CharsetEncoder. ...
- Java 字符编码(三)Reader 中的编解码
Java 字符编码(三)Reader 中的编解码 我们知道 BufferedReader 可以将字节流转化为字符流,那它是如何编解码的呢? try (BufferedReader reader = n ...
- python3中的编解码
#一个知识点是:python3中有两种字符串数据类型:str类型和 bytes类型:sty类型存储unicode数据,bytes类型存储bytes数据 #当我们在word上编辑文件的时候,数据保存之前 ...
- 搞清tomcat中的编解码
http://www.xuebuyuan.com/1287083.html *********************************** 经常会被乱码问题搅得头晕脑胀.事实上,乱码问题涉及的 ...
- 关于python中lambda 函数使用小结
例子: 如果定义普通函数,一般都是这样写: def:ds(x): return 2*x+1 调用即: ds(5) 如果用lambda函数就是这么写,就是一句话: g =lambda x:2*x+1 调 ...
- python中的变量引用小结
python的变量都可以看成是内存中某个对象的引用.(变量指向该内存地址存储的值) 1.python中的可更改对象和不可更改对象 python中的对象可以分为可更改(mutable)对象与不可更改(i ...
- python中的BeautifulSoup使用小结
1.安装 pip install beautifulsoup4 2.代码文件中导入 from bs4 import BeautifulSoup 3. 解析器 使用方法 优势 劣势 Python标准库 ...
- python中的requests使用小结
现接触到的很少,详细的官方教程地址: requests官方指南文档:http://docs.python-requests.org/zh_CN/latest/user/quickstart.html ...
- python中字符串编码方式小结
Python2中字符串的类型有两种:str和unicode,其中unicode是统一编码方式,它使得字符跟二进制是一一对应的,因此所有其他编码的encode都从unicode开始,而其他编码方式按照相 ...
随机推荐
- Linux curl 模拟form表单提交信息和文件
Linux curl 模拟form表单提交信息和文件 curl是一个命令行方式下传输数据的开源传输工具,支持多种协议:FTP.HTTP.HTTPS.IMAP.POP3.TELNET等,功能超级强大 ...
- Leetcode_num4_Reverse Integer
题目: Reverse digits of an integer. Have you thought about this? Here are some good questions to ask b ...
- 关于Android Animation的setFillBefore、setFillAfter和setFillEnable
1. 如果是独立的Animation,只有setFillAfter有效,设置为true动画结束后保持最后的状态 2. 如果是AnimationSet中的Animation,因为Animation的作用 ...
- push an existing repository from the command line
git remote add origin https://github.com/gaoconggit/LandMVC.git git push -u origin master
- JAVASCRIPT 浏览器兼容性问题及解决方案列表
JAVASCRIPT 浏览器兼容性问题及解决方案列表(1)获取HTML元素只兼容IE:document.all.hello hello 兼容所有: document.getElementById(“h ...
- Angular2 表单(一) 用户输入
绑定到用户输入事件 等号左边的 (click) 表示把按钮的点击事件作为绑定目标. 等号右边引号中的文本是模板语句,通过调用组件的 onClickMe 方法来响应这个点击事件. <button ...
- 我的Android进阶之旅------>MIME类型大全
今天在实现一个安装apk的代码中看到一段代码为:application/vnd.android.package-archive.不知其意.所以百度了一下,了解到这是一种MIME的类型,代表apk类型. ...
- iOS开发之 -- 判断是否第一次登陆APP
判断是否第一次登陆app,具体方法如下: if (![[NSUserDefaults standardUserDefaults]boolForKey:@"firstLaunch"] ...
- <span>和<div>标签的隐藏和显示切换
<div class="axb"> <span id="tipStep1" class="fl" >第一步显示< ...
- DOS和BAT批量提取修改文件名
DOS命令窗口:开始-cmd-回车,进入DOS命令窗口 案例一.获取文件名 dir 1.输入"文件所在盘",回车,如: d: 2.输入"cd 文件夹位置",回车 ...