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. git branch 分支和分支合并

    一般一个项目有一个默认的分支 master 主分支,然后可以有许多个分支,在别的分支上的操作不会影响到主分支.使用git branch查看当前多多少分支以及当前处于哪个分支上:执行git branch ...

  2. 5、如何快速找到多个字典中的公共键(key) 6 如何让字典保持有序 7 如何实现用户的历史记录功能(最多n条)

    5.如何快速找到多个字典中的公共键(key) from random import randint,sample #随机取数 # a = sample("ABCDEF",randi ...

  3. 【转】从SOA到微服务,企业分布式应用架构在云原生时代如何重塑

    摘要: SOA 采用中心化的服务总线架构,解耦了业务逻辑和服务治理逻辑:微服务架构回归了去中心化的点对点调用方式,在提升敏捷性和可伸缩性的同时,也牺牲了业务逻辑和服务治理逻辑解耦所带来的灵活性. 为了 ...

  4. 微信小程序开发之https服务器搭建三步曲

    本篇文章主要讲述3个方面的内容,如下: 1.SSL证书的获取 2.服务器 Nginx SSL 证书的配置. 3.如何兼容80端口和443端口以及为什么要同时兼容这两个端口. 1.SSL证书的获取 ht ...

  5. 22-4-isarry

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. redis 分析rdb中key

    1.问题: 单位一个redis集群内存报警,想找出所有的key的列表? 2.解决办法: 网上搜索是可以用redis-rdb-tools 这个工具进行分析 (1)centos6 默认安装python2. ...

  7. k8s 命令

    Kubernetes 常用安装和使用命令总结 获取所有命名空间上的pod kubectl get pod -o wide --all-namespaces 查看pod IP时使用 kubectl ge ...

  8. 第k小团+bitset优化——牛客多校第2场D

    模拟bfs,以空团为起点,用堆维护当前最小的团,然后进行加点更新 在加入新点时要注意判重,并且用bitset来加速判断和转移构造 #include<bits/stdc++.h> #incl ...

  9. TYVJ1061 Mobile Service

    P1061 Mobile Service 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 一个公司有三个移动服务员.如果某个地方有一个请求,某个员工必须赶到那 ...

  10. NX二次开发-UFUN获取工程图视图边界线颜色UF_DRAW_ask_border_color

    #include <uf.h> #include <uf_draw.h> #include <uf_ui.h> UF_initialize(); ; UF_DRAW ...