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. [USACO10FEB]购买巧克力Chocolate Buying

    题目描述 Bessie and the herd love chocolate so Farmer John is buying them some. The Bovine Chocolate Sto ...

  2. 了解GTIN小记

    GTIN为条形码,即"全球贸易项目代码"(Global Trade Item Number ) GTIN用作识别商品品项的全球性独一编码,是编码系统中应用最广泛的标识代码. GTI ...

  3. 浏览器http跳转至https问题

    Chrome 浏览器 地址栏中输入 chrome://net-internals/#hsts 在 Delete domain security policies 中输入项目的域名,并 Delete 删 ...

  4. 百度网盘Mac版如何分享链接?创建百度网盘 for Mac分享链接的方法

    想把自己百度网盘里的数据分享给朋友,该怎么操作呢?有很多朋友使用百度网盘,可以很轻松的自己的文件上传到网盘上,并可跨终端随时随地查看和分享.下面Mac down小编就给大家介绍一下创建百度网盘 for ...

  5. vue组件添加鼠标滚动事件

    在一个组件标签上加鼠标滚动事件,应该写成    @mousewheel.native

  6. delphi xe10 获取屏幕截图

    //截取屏幕图片 function MakeScaleScreenshot(Sender: TControl): TBitmap; function GetScreenScale: Single; v ...

  7. bzoj1059题解

    [解题思路] 因为只要验证可行性,所以考虑行和考虑列是等价的,故我们只考虑行的交换操作. 这样,拆一波点,把每一行拆成两个点,左边为原交换行,右边为目标交换行,原问题等价于能否对这个二分图进行完全匹配 ...

  8. NX二次开发-UFUN设置除工作层之外的所有图层的状态UF_LAYER_set_all_but_work

    NX11+VS2013 #include <uf.h> #include <uf_ui.h> #include <uf_layer.h> UF_initialize ...

  9. 微信小程序--跳转页面常用的两种方法

    一.bindtap="onProductsItemTap"绑定点击跳转事件 在.wxml文件中绑定 在.js文件中实现绑定事件函数 二.navigator标签配合URL跳转法 在w ...

  10. I/O与NIO(异步I/O)

    1.原来的I/O库与NIO最重要的区别是数据打包和传输方式的不同,原来的I/O以流的方式处理数据,而NIO以块的方式处理数据. 面向流的I/O系统一次一个字节地处理数据.一个输入流产生一个字节的数据, ...