文档章节

Python编码问题

 梦回雪夜观花
发布于 2016/02/03 00:25
字数 1758
阅读 320
收藏 7
点赞 1
评论 0

python的编码有点繁琐,在这里总结一下。

一、str与unicode

    python中有两种数据模型来支持字符串这种数据类型,str和unicode。它们的基类都是basestring。比如s = "中文"就是str类型的字符串,而u=u"中文"就是一个unicode类型的字符串。

    严格来说,str应该叫做字节串,它是unicode经过编码后的字节组成的序列。unicode是由str类型的字符串解码后得到,同时unicode也可以编码成str类型。

二、文件编码与头部编码声明

        python默认源代码文件是ascii编码,所以一旦出现不在ascii以外的字符(比如说中文字符)就会出现问题。所以如果在源代码中出现非ascii字符,需要在文件头部声明字符编码,声明凡是如下:

  # -*- coding: encoding -*-

        注意:这里声明的编码方式与最后文件存储的编码方式要一致!要一致!要一致!。

        (也就是说,头部的声明只是告诉python使用了encoding编码,至于最后编辑器保存的编码方式并不一定就是encoding。正确的做法是保证他们一致!正确的做法是保证他们一致正确的做法是保证他们一致!)

 原因:文件头部编码声明决定了python解析源码中的str的编码选择方式。比如头部声明的是utf-8编码,则代码中s="中文",python就会按照utf-8编码格式来解析。如果文件本身编码是gbk,而源码文件头部声明的编码是utf-8,这样如果源码中有中文就会有问题了,因为本身中文str存储是按照gbk编码来的,而python在解析str的时候又以为是utf-8编码,这样就会报SyntaxError: (unicode error) 'utf8' codec can't decode byte错误。

三、读写文件编码

        A)采用python的open()方法打开文件时。

        调用read()读取的是str,编码就是文件本身的编码。此时我们需要调用decode('文件本身编码')函数,将其从其本身的编码解码成unicode编码。

       调用write()写文件,

            1)如果参数是unicode编码字符串,则需要用指定编码encode该字符串,而不能直接write unicode编码字符串;

            2)如果write()参数是其他编码格式的str(不同于待写入文件编码),则需要先用该str的编码进行decode()成unicode编码字符串,然后再对该unicode字符串encode()成目标编码(待写入文件编码),然后在写                     入。

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

#头部声明的为utf-8
str_utf8 = '哈哈'

#unicode编码字符串
str_unicode = u'哈哈'

f = open('./gbktext.txt','w')

#将unicode成gbk
f.write(str_unicode.encode('gbk'))

#f.write(str_unicode)出错

#将utf-8解码成unicode,再编码成gbk
f.write(str_utf8.decode('utf-8').encode('gbk'))

f.close()

        B)为了保证编码正确常使用codecs模块,可以指定编码打开文件。

         调用read()读取的是unicode。

         调用write()写文件

               1)如果write()参数是unicode,则使用打开文件时的编码写入,

               2)如果write()参数是其他编码格式的str(不同于待写入文件编码),则需要先用该str的编码进行decode()成unicode编码字符串,然后在写入。

# -*- coding: utf-8 -*-
import codecs

def testCodecs():
    unicode_str = u"中文"
    #encode from unicode to utf-8
    utf8_str = unicode_str.encode('utf-8')
    #encode from unicode to gbk
    gbk_str = unicode_str.encode('gbk')
    
    filename = 'utf8_text.txt'
  
    wfp = codecs.open(filename, 'w', 'utf-8')
    
    #unicode字符串
    wfp.write(unicode_str)
    
    #先decode()成unicode
    wfp.write(gbk_str.decode('gbk'))
    
    wfp.flush()
    wfp.close() 
    
    #read file in utf-8
    rfp = codecs.open(filename, 'r','utf-8')
    str_type = rfp.read()
    
    #读出的类型是unicode ==> type(str_type) =  <type 'unicode'>  
    print 'type(str_type) = ',type(str_type)
    
if __name__ == "__main__":
    testCodecs()

四、其他注意事项

        1、windows控制台中文编码是GBK,Python的IDLE编码也是GBK

    

   

        但这里为什么不是中文字符"哈哈哈"而是'\xb9\xfe\xb9\xfe\xb9\xfe',其实这里输出的是“哈哈哈”的GBK编码的16进制形式(他是正确的)。为什么print的时候确实是"哈哈哈"?

    When Python executes a print statement, it simply passes the output to the operating system (using fwrite() or something like it), and some other program is responsible for actually displaying that output on the screen.

    To print data reliably, you must know the encoding that this display program expects.

    也就是说当调用print的时候它仅仅是将字符串传给了操作系统,至于如何显示是由其他的program负责的(比如windows终端,IDLE),负责显示的program会对传入的字符串进行编码。所以要想获得可靠的输出,必须要知道负责输出的program的编码(并与负责显示的program的编码一致)。

    print的时候显示是由python IDLE负责,也就是按GBK解释,打印自然是"哈哈哈"

    将其decode()的时候可以得到正确的unicode字符串 u'\u54c8\u54c8\u54c8',当print unicode字符串的时候,自动以GBK(负责显示的program所使用的编码) encode()然后显示,所以打印也是"哈哈哈"。

    也就是说要想获得正确的显示,必须保证print的字符串编码格式与终端(负责显示的终端编码格式)一致!

    但是,如果要显示的字符串中包含有负责显示program(如windows终端)所使用编码不会包含的字符会怎样?

    对,会出错。比如,当此unicode字符串中包含某特殊字符,而目标终端的编码集合中没有此字符,则很明显也是无法实现将Unicode编码为对应的特定编码的字符串,无法正确显示的。

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

slashUStr = "\\u3232\\u6674"; #(有) 晴

decodedUniChars = slashUStr.decode("unicode-escape");
#如果没有打印的刚性需求的话,我们完全可以选择不打印,直接进行下一步的处理
#因为此处已经可以正常获得对应的两个Unicode字符了,完全可以继续进行后续处理
unicodeButContainSpecialChar = decodedUniChars;

print "unicodeButContainSpecialChar=",unicodeButContainSpecialChar;

    他在Python IDLE中其实显示是正确的(原因不明,先忽略)。如果在windows 终端显示,会按预期的出错(#UnicodeEncodeError: 'gbk' codec can't encode character u'\u3232' in position 0: illegal multibyte sequence),因为他包含GBK字符集不包含的字符,
 Unicode字符:0x3232,是个特殊字符,而此字符,不在GBK编码字符集。

    但是还有一种办法可以解决。  

s.encode("gbk", "ignore");
#忽略掉无法正确编码的字符

#假设s试试utf-8编码,按gbk解码肯定有问题,若非要解码
s.decode('gbk','ignore')
#忽略掉无法正确解码的字符

2、windows记事本问题

        在window下面用记事本编辑文件的时候,如果保存为UNICODE或UTF-8,分别会在文件的开头加上两个字节“\xFF\xFE”和三个字节“\xEF\xBB\xBF”。在读取的时候就可能会遇到问题。(windows控制台,python shell下有问题,pythonIDLE正常)

    

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

f = open('./utf8.txt','r').read()

print f

print f.decode('utf-8')[1:]

    

   五、参考

        http://www.cnblogs.com/huxi/archive/2010/12/05/1897271.html

        http://www.crifan.com/python_already_got_correct_encoding_string_but_seems_print_messy_code/

        

        

© 著作权归作者所有

共有 人打赏支持
粉丝 8
博文 13
码字总数 16693
作品 0
武汉
程序员
python中#!/usr/bin/python与#!/usr/bin/env python的区别

目的是在运行python脚本的时候告诉操作系统我们要用python解释器去运行py脚本 所以我们在第一句往往会写如下两句中的其中一句: 或 就是说在没有在执行程序时指出用什么程序运行py脚本时,系统...

p柯西 ⋅ 06/15 ⋅ 0

深入浅出地,彻彻底底地理解python中的编码

作者:milter 链接:https://www.jianshu.com/p/eb22cee6c553 1问题1:问题在哪里? 问题是我们的靶子,心中没有问题去学习就会抓不住重点。 本文使用的编程环境是centos6.7,python2.7。 我...

机器学习算法与自然语言处理 ⋅ 05/02 ⋅ 0

Python 2 和 Python 3 主要区别有哪些(一)?

Guido(Python之父,仁慈的独裁者)在设计 Python3 的过程中,受一篇文章 “Python warts” 的影响,决定不向后兼容,否则无法修复大多数缺陷。---摘录自《流畅的Python》 你可能从来没有听说...

liuzhijun ⋅ 2017/08/02 ⋅ 0

人人都能学会的python编程教程3:字符串和编码

字符串 在python3中已经全面支持中文。 由于Python源代码也是一个文本文件,所以,当你的源代码中包含中文的时候,在保存源代码时,就需要务必指定保存为UTF-8编码。当Python解释器读取源代码...

编程老司机 ⋅ 05/10 ⋅ 0

python基础autopep8__python代码规范

关于PEP 8 PEP 8,Style Guide for Python Code,是Python官方推出编码约定,主要是为了保证 Python 编码的风格一致,提高代码的可读性。 官网地址:https://www.python.org/dev/peps/pep-0...

_周小董 ⋅ 05/01 ⋅ 0

Python爬取拉勾网数据分析职位

python文件打开方式详解——a、a+、r+、w+区别 Python模块学习 - openpyxl 1.信息获取,所需工具:拉勾网、Python3。 原来课程地址:python拉勾网爬虫 反爬:伪造浏览器请求 'User-Agent':'...

sinat_23880167 ⋅ 05/27 ⋅ 0

[自动化实战」总结从python2.7和python3.0的语法差异

我的实战课《python自动化运维实战》经过了一年的设计,工程是基于python2.7版本开发而成。 Python 2/3的思想基本是共通的,只有少量的语法有差别甚至不兼容。当对Python熟悉到一定程度时, ...

幕客技术 ⋅ 01/14 ⋅ 0

Python基础——内置hashlib、IO、Json、codecs模块(0426)

一、hashlib 加密模块:提供了很多加密的算法 常见的加密方式:MD5 RSA,加密之后不可逆。没法破解。 1、以MD5的方式加密字符串(Python 3) 示例 结果 2、以MD5的方式加密字符串(Python 2)...

python初雪之路 ⋅ 04/27 ⋅ 0

《Python从小白到大牛》简介

本书是一部系统论述Python编程语言、OOP编程思想以及函数式编程思想的立体化教程(含纸质图书、电子书、教学课件、源代码与视频教程)。为便于读者高效学习,快速掌握Python编程方法。本书作...

tony关东升 ⋅ 05/29 ⋅ 0

复习0610—Python数据类型

程序就是 算法 + 数据结构 Python 中,自带数据类型。常见的数据类型包括:数值类型、字符串类型、群集类型。 一、数值类型 在Python中,数值类型包括整型、浮点型、布尔型、复数型。 【1】整...

python初雪之路 ⋅ 06/10 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

IDEA创建SpringMVC+Mybatis+Maven项目

视频如下(加载有点慢请见谅,服务器不太好): 视频

影狼 ⋅ 5分钟前 ⋅ 0

前阿里P8架构师:精准定制Java架构师学习计划!

可以说,Java是现阶段中国互联网公司中,覆盖度最广的研发语言,掌握了Java技术体系,不管在成熟的大公司,快速发展的公司,还是创业阶段的公司,都能有立足之地。 有不少朋友问,除了掌握J...

java高级架构牛人 ⋅ 8分钟前 ⋅ 0

zookeper学习

https://blog.csdn.net/u012152619/article/category/6470028

~少司命~ ⋅ 9分钟前 ⋅ 0

Spring MVC ,JSON,JQuery,不懂JQuery,跳过了

/spring-mvc-study/src/main/webapp/course_json.jsp <%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD ......

颖伙虫 ⋅ 9分钟前 ⋅ 0

2018上海云栖大会workshop-日志数据采集与分析对接

摘要: 日志数据采集与分析对接 课程描述 通过日志服务采集用户、数据库、业务等访问数据。演示对于业务日志分析与处理,程序日志查询与监控,打通日志与数据仓库对接案例。 日志种类 网站访...

阿里云云栖社区 ⋅ 10分钟前 ⋅ 0

mahout demo

package com.datamine.CollaborativeFiltering.mysql; import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood; import org.apache.mahout.cf.taste.impl.recommend......

xiaomin0322 ⋅ 12分钟前 ⋅ 0

red hat openstack 12配置要求

安装 openstack 之前,一般要规划整个系统中,到底要多少台机器来参与openstack, 根据rhosp12的官方文档: 最低要求是3台物理机,1台作为director,一台作为 controller ,一台作为computer....

tututu_jiang ⋅ 13分钟前 ⋅ 0

Rocket-Chip在GitHub上的各个源码

在github上通过搜索Rocket-chip可以得到36个结果:其中 https://github.com/freechipsproject/rocket-chip https://github.com/ucb-bar/riscv-boom https://github.com/ucb-bar/fpga-zynq (......

whoisliang ⋅ 18分钟前 ⋅ 0

【HAVENT原创】CentOS 6.5 下 Nginx 的安装与配置

nginx是轻量级的Web服务器、反向代理服务器及邮件服务器,具有占用内存少,并发能力强的优点,已被广泛应用。本文介绍目前最新版本 1.12.2 的安装。 各版本nginx下载地址:http://nginx.org/...

HAVENT ⋅ 24分钟前 ⋅ 0

查看linux系统重启之前的log -- last_kmsg

当 Linux Kernel 出现 BUG 的时候,后走入 panic flow,这个时候由于 Kernel 出现了严重的问题,adbd 也无法响应 adb 连接请求,这个时候想透过读取 Kernel Log Buffer 来看 Kernel Log 是不...

zyzzu ⋅ 25分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部