py2编码

tr和unicode

str和unicode都是basestring的子类。严格意义上说,str其实是字节串,它是unicode经过编码后的字节组成的序列。对UTF-8编码的str'苑'使用len()函数时,结果是3,因为utf8编码的'苑' == '\xe8\x8b\x91'。

而unicode是一个字符串,str是unicode这个字符串经过编码(utf8,gbk等)后的字节组成的序列。如上面utf8编码的字符串'汉'。

unicode才是真正意义上的字符串,对字节串str使用正确的字符编码进行解码后获得,并且len(u'苑') == 1。

在Py2里,str=bytes。

py2编码的最大特点是Python 2 将会自动的将bytes数据解码成 unicode 字符串

所以在2里我们可以将字节与字符串拼接。

两个问题:

1 print '苑昊' :本来存的是'\xe8\x8b\x91\xe6\x98\x8a',为什么显示了 苑昊 的明文?

2 字节串和字符串可以拼接?

这就是那些可恶的 UnicodeError 。你的代码中包含了 unicode 和 byte 字符串,只要数据全部是 ASCII 的话,所有的转换都是正确的,一旦一个非 ASCII 字符偷偷进入你的程序,那么默认的解码将会失效,从而造成 UnicodeDecodeError 的错误。

Python 2 悄悄掩盖掉了 byte 到 unicode 的转换,让程序在处理 ASCII 的时候更加简单。你复出的代价就是在处理非 ASCII 的时候将会失败。

  

再来看看encode()和decode()两个basestring的实例方法,理解了str和unicode的区别后,这两个方法就不会再混淆了:

py3编码

python3 renamed the unicode type to str ,the old str type has been replaced by bytes.

跟 Python 2 类似,Python 3 也有两种类型,一个是 Unicode,一个是 byte 码。但是他们有不同的命名。

现在你从普通文本转换成 “str” 类型后存储的是一个 unicode, “bytes” 类型存储的是 byte 串。你也可以通过一个 b 前缀来制造 byte 串。

Python 3最重要的新特性大概要算是对文本和二进制数据作了更为清晰的区分。文本总是Unicode,由str类型表示,二进制数据则由bytes类型表示。Python 3不会以任意隐式的方式混用str和bytes,正是这使得两者的区分特别清晰。你不能拼接字符串和字节包,也无法在字节包里搜索字符串(反之亦然),也不能将字符串传入参数为字节包的函数(反之亦然)。这是件好事。

Python 3 中对 Unicode 支持的最大变化就是将会没有对 byte 字节串的自动解码。如果你想要用一个 byte 字节串和一个 unicode 相链接的话,你将会得到一个错误,不管你包含的内容是什么。

所有这些在 Python 2 中都将会有隐式的处理,而在 Python 3 中你将会得到一个错误。

注意:无论py2,还是py3,与明文直接对应的就是unicode数据,打印unicode数据就会显示相应的明文(包括英文和中文)

编码实现

说到编码,我们需要在全局掌握这个工作过程,比如我们在pycharm上编写一个.py文件,从保存到运行数据到底是怎么转换的呢?

在解决这个问题之前,我们需要解决一个问题:默认编码

默认编码

什么是默认编码?其实就是你的解释器解释代码时默认的编码方式,在py2里默认的编码方式是ASCII,在py3里则是utf8(sys.getdefaultencoding()查看)。

1
#-*- coding: UTF-8 -*-

这个声明是做什么的?我们在最开始只知道在py2里如果不加上这么一句话,程序一旦出现中文就会报错,其实就是因为py2默认的ASCII码,对于中文这些特殊字符无法编码;

声明这句话就是告诉python2.7解释器 (默认ACSII编码方式)解释hello.py文件声明下面的内容按utf8编码,对,就是编码(编码成字节串最后转成0101的形式让机器去执行) 

大家注意hello.py文件保存时有自己特定的编码方式,比如utf8,比如gbk。

需要注意的是声明的编码必须与文件实际保存时用的编码一致,否则很大几率会出现代码解析异常。现在的IDE一般会自动处理这种情况,改变声明后同时换成声明的编码保存,但文本编辑器控们需要小心。所以,保存的编码样式取决于你的编辑器默认的样式(可调)。

文件保存和执行过程

我们讲过,字符串在内存中是以unicode的数据形式保存的,可什么时候我们数据是在内存呢?让我们一起解析这个过程

比如我们在pycharm上(py3.5)创建一个hello.py文件:

1
print('hello 星星')

这个时候我们的数据在内存吗?NO,它已经被pycharm以默认的文件保存编码方式存到了硬盘(二进制数据),所以一定注意,你点击运行的时候,其实首先需要打开这个文件,然后将所有的数据转移到内存,字符串此时就以unicode的数据格式存到内存的某块地址上(为什么要这样处理一会讲到),其它内容还是utf8的编码方式,然后解释器就可以按着默认的utf8的编码方式逐行解释了。 

所以,一旦你的文件保存时的编码与解释器解释的编码不一致时就会出现错误。

常见编码错误

1 cmd下的乱码问题

hello.py

#coding:utf8

print ('星星')

文件保存时的编码也为utf8。

思考:为什么在IDE下用2或3执行都没问题,在cmd.exe下3正确,2乱码呢?

我们在win下的终端即cmd.exe去执行,大家注意,cmd.exe本身就是一个软件;当我们python2 hello.py时,python2解释器(默认ASCII编码)去按声明的utf8编码文件,而文件又是utf8保存的,所以没问题;问题出在当我们print'苑昊'时,解释器这边正常执行,也不会报错,只是print的内容会传递给cmd.exe显示,而在py2里这个内容就是utf8编码的字节数据,而这个软件默认的编码解码方式是GBK,所以cmd.exe用GBK的解码方式去解码utf8自然会乱码。

py3正确的原因是传递给cmd的是unicode数据,符合ISO统一标准的,所以没问题。

1
print (u'星星')

改成这样后,cmd下用2也不会有问题了。 

2  print问题

在py2里

1
2
3
#coding:utf8
print ('星星') #星星
print (['星星','xing']) #['\xe8\x8b\x91\xe6\x98\x8a', 'xing']

在py3里

1
2
print ('星星') #星星
print (['星星','xing']) #['星星', 'xing']

python3和python2编码拾遗的更多相关文章

  1. python2和python3中的编码问题

    开始拾起python,准备使用python3, 造轮子的过程中遇到了编码的问题,又看了一下python3和python2相比变化的部分. 首先说个概念: unicode:在本文中表示用4byte表示的 ...

  2. python3中的编码与解码(超好理解)

    编码和解码是针对数据而言的,数据能干什么呢?无非就是用来显示,储存和传输的: 储存和传输数据当然是希望数据越小越好,所以发明了utf-8这种数据编码显示:它智能将英文用一个字节表示,欧洲的字符用两个字 ...

  3. python2编码问题

    前言:python3解决了编码的问题,但python2还存在很多编码问题,用P2写爬虫爬了网页,解析时常有不同字符混着编码,导致解码问题成为爬虫程序员的噩梦... 但咱们要用robot framewo ...

  4. python3中的编码

    python2字符串编码存在的问题: 使用 ASCII 码作为默认编码方式,对中文处理不友好 把字符串分为 unicode 和 str 两种类型,将unicode作为唯一内码,误导开发者 python ...

  5. Python3与Python2的差异

    基于python3浅谈python3与python2的差异.由于现今主流Python3,但是之前用Python2做的项目,还得维护,所以作为python工作者,不免要了解其中差异,其中,Python2 ...

  6. python3与python2使用python原生SimpleHTTPRequestHandler

    python3 使用时如下: #!/usr/bin/env python3 #coding=utf-8 from http.server import SimpleHTTPRequestHandler ...

  7. 同时装了Python3和Python2,怎么用pip?

    问题:同时装了Python3和Python2,怎么用pip? Ubuntu13.04, 系统内同时装了Python3.3 和 2.7 用sudo apt-get install python-pip ...

  8. Python3.X-文本编码问题

    1.请说明python2与python3的默认编码是什么? python的默认编码是ASCII码,python3的默认编码是utf-8 2.为什么会出现中文乱码?能列举出现乱码的情况有哪几种么? 编码 ...

  9. Win10下python3和python2同时安装并解决pip共存问题

    特别说明,本文是在Windows64位系统下进行的,32位系统请下载相应版本的安装包,安装方法类似. 使用python开发,环境有Python2和 python3 两种,有时候需要两种环境切换使用,下 ...

随机推荐

  1. ubuntu安装WPS替代office

    安装 1.下载地址:http://community.wps.cn/download/(去WPS官网下载) 下载第一个即可 2.执行安装命令: sudo dpkg -i wps-office_10.1 ...

  2. 基于OpenResty与Consul实现服务网格ServiceMesh

    一.逻辑架构 1.基于OpenResty开发智能代理: 利用其动态可编程特性,动态化配置nginx服务路由: 2.需要向OpenResty添加weibo开源的upsync服务发现模块: 3.基于con ...

  3. 关于springmvc与ajax的交互-开发记录

    每次都栽在这个地方,好衰! 在jsp页面的<form>标签设置了action="请求url" ,button那里用js进行监听,点击触发ajax方法,将前台数据传到后台 ...

  4. Java—Map浅入

    写支付签名的时候遇到了Map一家,就简单的比较了一下,于是乎先打印看看结果 Map<String,String> hashMap1 = new HashMap<>();hash ...

  5. Spring - @ManagedResource, @ManagedOperation, @ManagedAttribute

    总结 通过annotation (@ManagedResource, @ManagedOperation, @ManagedAttribute)注解注册MBean到JMX实现监控java运行状态 参考 ...

  6. HTML——表格标签

    存在即是合理的. 表格的现在还是较为常用的一种标签,但不是用来布局,常见处理.显示表格式数据. 创建表格 在HTML网页中,要想创建表格,就需要使用表格相关的标签.创建表格的基本语法格式如下: < ...

  7. JZOJ5143:无心行挽

    Description “What’s left to do when we’ve lost all hope?”“若内心万念俱灰,是否注定无心行挽?”------来自网易云音乐<Golden ...

  8. 57 c++ 读取二进制文件: 以.raw后缀的TDF_Voxel_Size文件为例

    0 引言 毕业设计中用到了.raw格式的文件,需要将该文件按照M*N*P的矩阵格式加载到内存中.采用 #include <fstream> 中的FILE* 加载,并针对数据占用字节数,以 ...

  9. weblux上传图片

    我是接口接收图片然后上传到阿里云上,由于引入的是spring weblux,所以使用方式不同,代码如下 @PostMapping(value = "/upload", consum ...

  10. NX二次开发-UFUN选择草图对话框UF_UI_select_sketch

    #include <uf.h> #include <uf_ui.h> UF_initialize(); //选择草图对话框 char sMessage[] = "选择 ...