在用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中的编解码小结的更多相关文章

  1. Java 字符编码(二)Java 中的编解码

    Java 字符编码(二)Java 中的编解码 java.nio.charset 包中提供了一套处理字符编码的工具类,主要有 Charset.CharsetDecoder.CharsetEncoder. ...

  2. Java 字符编码(三)Reader 中的编解码

    Java 字符编码(三)Reader 中的编解码 我们知道 BufferedReader 可以将字节流转化为字符流,那它是如何编解码的呢? try (BufferedReader reader = n ...

  3. python3中的编解码

    #一个知识点是:python3中有两种字符串数据类型:str类型和 bytes类型:sty类型存储unicode数据,bytes类型存储bytes数据 #当我们在word上编辑文件的时候,数据保存之前 ...

  4. 搞清tomcat中的编解码

    http://www.xuebuyuan.com/1287083.html *********************************** 经常会被乱码问题搅得头晕脑胀.事实上,乱码问题涉及的 ...

  5. 关于python中lambda 函数使用小结

    例子: 如果定义普通函数,一般都是这样写: def:ds(x): return 2*x+1 调用即: ds(5) 如果用lambda函数就是这么写,就是一句话: g =lambda x:2*x+1 调 ...

  6. python中的变量引用小结

    python的变量都可以看成是内存中某个对象的引用.(变量指向该内存地址存储的值) 1.python中的可更改对象和不可更改对象 python中的对象可以分为可更改(mutable)对象与不可更改(i ...

  7. python中的BeautifulSoup使用小结

    1.安装 pip install beautifulsoup4 2.代码文件中导入 from bs4 import BeautifulSoup 3. 解析器 使用方法 优势 劣势 Python标准库 ...

  8. python中的requests使用小结

    现接触到的很少,详细的官方教程地址: requests官方指南文档:http://docs.python-requests.org/zh_CN/latest/user/quickstart.html ...

  9. python中字符串编码方式小结

    Python2中字符串的类型有两种:str和unicode,其中unicode是统一编码方式,它使得字符跟二进制是一一对应的,因此所有其他编码的encode都从unicode开始,而其他编码方式按照相 ...

随机推荐

  1. SQL Server 数据库同步,订阅、发布、复制、跨服务器

    随便说两句 折腾了一周,也算把数据库同步弄好了.首先局域网内搭建好,进行各种测试,弄的时候各种问题,弄好以后感觉还是挺简单的.本地测试好了,又在服务器进行测试,主要的难点就是跨网段同步,最后也解决了, ...

  2. 利用CSS生成精美细线Table表格

    精美的表格是前端开发用到的一个组件,很多时候我们利用复杂的页面style代码,来生成这样的表格,造成了页面的修改性和可读性都非常差.这里推荐直接使用css来产生一个细线表格. 使用方法也很简单: 第一 ...

  3. DTD与XML Schema都是XML文档。(选择1项)

    DTD与XML Schema都是XML文档.(选择1项) A.正确 B.不正确 解答:DTD不是XML文件, schema是XML文档

  4. 对特殊字符编码js与c#中的处理方法

    js: encodeURIComponent();编码 c#: Uri.UnescapeDataString();解码

  5. RabbitMQ之Queues-5

    工作队列的主要任务是:避免立刻执行资源密集型任务,然后必须等待其完成.相反地,我们进行任务调度:我们把任务封装为消息发送给队列.工作进行在后台运行并不断的从队列中取出任务然后执行.当你运行了多个工作进 ...

  6. Ubuntu 16.04 LTS 安装libvips出现”Package vips was not found in the pkg-config search path”

    使用libvips来操作图像,libvips的部署参考一个Node.js工程:https://github.com/lovell/sharp 在MAC下安装很顺利,到Linux环境下(Ubuntu 1 ...

  7. 配置使用TargetFrameworks输出多版本类库

    1.类库右键 2.修改配置 修改前: <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <Targe ...

  8. GSAP 官方文档(结贴)

    好久没写GSAP的教程的(其实我也不懂哈哈),国内也没什么人用,不对动画要求特别高的话,其实也没必要用GSAP,现在工作上没用到这个东西,也懒得写了,所以有问题的话去找一下greensock的官方文档 ...

  9. Github Pages建立个人博客

    使用Github Pages可以建立个人博客.官方教程:https://pages.github.com/步骤(以下步骤中假设用户名为username):1.建立一个项目,项目名为username.g ...

  10. map重写比较器

    结构体作为map的key或放入set中,需要重载<运算符,如下: typedef struct tagRoadKey { int m_i32Type; int m_i32Scale; bool ...