从Python发展历史谈起

Python3和Python2表示字符序列的方式有所不同。

  • Python3字符序列的两种表示为byte和str。前者的实例包含原始的8位值,即原始的字节;后者的实例包括Unicode字符。
  • Python2字符序列的两种表示为str和unicode。与Python3不同的是,str实例包含原始的8位值;而unicode的实例,则包含Unicode字符。

类型转换

把Unicode字符表示为二进制数据有许多方法。做常见的编码方式是UTF-8。但是python3的str实例和Python2的unicode实例都没有和特定的二进制编码形式相关联。要想把Unicode字符转换为二进制数据,就必须使用encode方法。要想把二进制数据转换成Unicode字符,则必须使用decode方法。

因此,在编写大型复杂的Python程序的时候,一般把编码和解码的相关操作放到最外层来做。程序核心部分使用Unicode字符类型,也就是Python3的str以及Python2的unicode,而且不要对字符编码做任何假设。这种办法既可以让程序接受多种类型的文本编码,又可以保证输出的文本信息只采用一种编码形式(最好是UTF-8),灵活性很高。

所以,可以编写两个辅助函数,以便对序列进行转换,使得转换后的输入数据符合开发者预期。

对于Python3

在Python3中,我们需要编写一个接收str或bytes,并总是返回str的方法:

def to_str(bytes_or_str):if isinstance(bytes_or_str, bytes):return bytes_or_str.decode('utf-8')return bytes_or_str # instance of str 

以及一个总是返回bytes的方法:

def to_bytes(bytes_or_str):if isinstance(bytes_or_str, str):return bytes_or_str.encode('utf-8')return bytes_or_str # instance of bytes

对于Python2

在Python2中,我们需要编写一个接收str或unicode,并总是返回unicode的方法:

def to_unicode(unicode_or_str):if isinstance(unicode_or_str, str):return unicode_or_str.decode('utf-8')return unicode_or_str # instance of unicode

以及一个总是返回str的方法:

def to_str(unicode_or_str):if isinstance(unicode_or_str, unicode):return unicode_or_str.encode('utf-8')return unicode_or_str # instance of str

面临的问题

在Python中使用原始8位值与Unicode字符时,通常有两个问题需要注意。

第一个问题

第一个问题通常出现在Python2中,如果你用的是Python3,可以暂且忽略这个问题。

如果str只包含7位的ASCII字符,那么unicode和str实例似乎就成了同一种类型。

  • 可以用+操作符把str与unicode连接起来
  • 可以进行比较操作比如, ==!=、<、>

这些行为一位着,只处理7位的ASCII的情况下,如果某个函数接受str,那么可以给它传入unicode;如果某个函数接收unicode,也可以传入str。而在Python3中,bytes和str实例绝对不会等价,更不能进行比较,即使是空字符串也不可以,因为这是完全不同的两个类型。所以,在传入字符序列的时候必须留意其类型。

第二个问题

第二个问题可能会出现在Python3上,也是经常遇到的一些问题。

如果通过内置的open函数获取讴歌文件句柄,那么需要注意的是,该句柄默认会采用UTF-8编码格式来操作文件。而在Python2中,文件操作的默认格式是二进制的,这可能会导致程序出现奇怪的错误。

例如,现在要向文件中随机写入二进制数据,下面这个写法在Python2中不会有什么问题,但在Python3中会有异常,提示TypeError: write() argument must be str, not bytes

with open('./random.bin', 'w') as f:f.write(os.urandom(10))>>> TypeError: write() argument must be str, not bytes

发生上述问题的原因是Python3给open函数添加了encode参数,而这个新参数的默认值是UTF-8。这样一来,系统就会要求开发者必须传入包含Unicode字符的str实例,而不是包含二进制数据的bytes实例。

为了解决这个问题,我们必须用二进制写入模式,即将原来的'w'修改为'wb',这样一来就可以同时适配Python2和Python3。从文件中读取数据的时候也会有类似的问题,解决方法与写入类似,使用'rb'模式打开文件,而不是'r'模式。

总结

  1. 在Python3中,bytes是一种包含8位值的序列,str是一种包含Unicode字符的序列。开发者不用比较操作来混合处理。
  2. 在Python2中,str是一种包含8位值的序列,unicode是一种包含Unicode字符的序列。如果str只有7位ASCII字符,那么可以进行比较运算以及连接操作。
  3. 在对输入的数据操作之前,使用辅助函数来保证字符序列的类型与开发者的期望一致。
  4. 从文件中读取二进制数据,或向其中写入二进制数据时,总应该以'rb'或'wb'等二进制模式来开启文件。

参考阅读:

《Effective Python》

mfc从文件中读取数据_Python 中的 bytes、str 以及 unicode 区别相关推荐

  1. mfc从文件中读取数据_Java中Transient关键字,一点课堂(多岸学院)

    Java中Transient关键字 虽然自己最熟的是Java,但很多Java基础知识都不知道,比如transient关键字以前都没用到过,所以不知道它的作用是什么,今天做笔试题时发现有一题是关于这个的 ...

  2. python从文件中读取数据_Python3 中把txt数据文件读入到矩阵中的方法

    下面为大家分享一篇Python3 中把txt数据文件读入到矩阵中的方法,具有很好的参考价值,希望对大家有所帮助.一起过来看看吧 1.实例程序: ''' 数据文件:2.txt内容:(以空格分开每个数据) ...

  3. python有什么库可以 从fig文件中读取数据_Python之matplotlib库学习:实现数据可视化...

    1. 安装和文档 pip install matplotlib 为了方便显示图像,还使用了ipython qtconsole方便显示.具体怎么弄网上搜一下就很多教程了. pyplot模块是提供操作ma ...

  4. kettle读取json文件并读取数据_kettle中JSON数据解析

    前言 关于kettle的JSON字符串的解析已经困扰我们很长时间了,我们知道kettle中有JSON输入控件,但这个控件用的JSONPATH语法折腾了几次都没闹明白,之前我们一直都是采取写插件使用fa ...

  5. 查看mysql是否内存中读取数据_MySQL中的内存临时表

    //MySQL中的内存临时表// 这两天事情稍微有点多,公众号也停止更新了几天,结果有读者催更了,也是,说明还是有人关注,利己及人,挺好. 今天分享的内容是MySQL中的临时表,对于临时表,之前我其实 ...

  6. java 从excel中读取数据_java中怎样从Excel中读写数据

    展开全部 public class ReadExcel001 { public static void main(String[] args) { readXml("D:/test.xlsx ...

  7. python读取xls数据_python_从.mat与.xls类型文件中读取数据

    从.xls类型文件中读取数据 在写机器学习算法的时候从UCI下载了一些数据,但是格式不是csv,而是.txt/.data,可以先用excel打开数据,在excel中将数据进行分列后导入python进行 ...

  8. python print(len(pi_string))_Python如何从文件中读取数据

    从文件中读取数据 1. 读取整个文件 要读取文件,首先来创建一个文件: 然后打开并读取这个文件,再将其内容显示到屏幕上:file_reader.py with open('pi_digits.txt' ...

  9. 从文件中读取一个long型数_Python 从文件中读取数据

    问题:在python中如何从文件中读取数据,比如有一个mydata.txt文件包含10000行,50列的数据,想提取某几列出来,比如1, 3,5列. 方法一,编一个读取数据的函数. import js ...

最新文章

  1. CentOS7.X的系统管理、安全设置及系统优化思路
  2. gedit乱码 fedora
  3. Servlet 3.0 新特性详解
  4. LeetCode 1799. N 次操作后的最大分数和(回溯 / 状态压缩DP)
  5. 多目标跟踪评价标准(MOT)
  6. 背包之01背包、完全背包、多重背包详解
  7. [IOS]使用UIScrollView和UIPageControl显示半透明帮助蒙板
  8. 增广拉格朗日 matlab,大连理工优化方法增广拉格朗日方法MATLAB程序
  9. 高德poi类别23个大类 261个中类 4705个小类
  10. 今天准备出发去珠海横琴,去长隆海洋乐园看鲨鱼宝宝了
  11. 又一个 Jupyter 神器,操作 Excel 自动生成 Python 代码
  12. nload0.7.2编译及使用说明
  13. Windows下配置Git连接上github, 并将本地文件夹同步(加入了个人注释)
  14. Android实例之必应每日一图
  15. 我需要一块二向箔,清理用(模拟)
  16. 四轮 控制算法 麦轮_纯野生黑科技,分分钟教你自制最skr的全向麦熊小车!
  17. QEMU翻译块(TB)分析
  18. 2009年三季度基金持股减仓表1
  19. 计算机游戏攻略70,70亿人攻略大全 七十亿人全关卡双星代码通关攻略
  20. 网站云服务器1核和2核区别,购买服务器1核和2核是什么意思?区别是什么?

热门文章

  1. 使用Maven进行增量构建
  2. 医疗保健数据接口_应用的大数据:医疗保健的经济学
  3. guava api_使用Google Guava的订购API
  4. JavaFX动画工具
  5. mockito 使用_用Mockito回答
  6. 学习Netflix管理员–第1部分
  7. 使用Zapier将应用程序与Neo4j集成
  8. 玩Java 8 – Lambda,路径和文件
  9. 使用AspectJ审计Spring MVC Webapp。 第2部分
  10. Spring MVC:测试简介