详解Python3.1版本带来的核心变化


Posted in Python onApril 07, 2015

这里我们将对Python 3.1核心语言的变化进行分析,包括字符串的格式化、说明符以及其他方面的内容。希望这些变化能对大家了解Python 3.1有所帮助。

Python 3.0发布七个月之后,Python核心开发人员于2009年6月27日发布了新的Python 3.1版本。虽然此3.1版本只是对Python 3.0的一次小型升级,但是它不仅为开发者带来许多让人感兴趣的特性,同时在性能方面也有所改善。本文将为读者详细介绍Python 3.1版本在核心语言、标准程序库和性能改善方面的变化。

一、字符串的格式化

Python的最新版本为我们带来了讨人喜欢的格式字段的自动填数功能。我们知道,许多程序中经常需要格式化字符串。Python 2.x版本使用的是类似[s]printf函数的百分号操作符,如下所示:

>>> '%s, %s!' % ('Hello', 'World')

'Hello, World!'而Python 3.0则添加了更高级的字符串格式化功能,如下所示:

>>> '{0}, {1}!'.format('Hello', 'World')

'Hello, World!'如今,Python 3.1则在字符串格式化方面又有了新的改进。对于Python 3.0来说,每当您想在格式串中引用位置参数时,您必须给出每个位置参数的索引。但是在Python 3.1中,您就可以将这些索引抛在脑后了,因为Python会依次替您填充这些参数:

>>> '{}, {}!'.format('Hello', 'World') 
  'Hello, World!'

二、PEP-378:用于千位分隔符的格式说明符

在财务应用程序中,通常要在数字中使用千位分隔符。从事金融或者财会方面工作的人士是不这样写的“您欠我$12345678”,而是“您欠我$12,345,678”,他们惯于使用逗号作为分隔符。那么,如何使用Python达到这种效果呢:

>>> format(12345678, ',')

'12,345,678'您可以利用其他区分符对数字进行分组。这里的宽度说明符(这里为8)包括了逗号和小数点:

 

>>> format(1234, ',').replace(',', '_')

'12,345.7'逗号通常作为默认的分隔字符,如果要使用其他字符作为分隔字符的话,只需通过replace函数用您喜欢的字符替换逗号即可,具体如下所示:

>>> format(1234, ',').replace(',', '_')

'1_234'当然,您还可以使用format函数来作为字符串方法:

>>> '{0:8,.1f}'.format(123.456)

三、Maketrans函数

利用maketrans()和translate()函数,我们可以使用一组字符来替换另一组字符。使用这一替换功能时,多少有点繁琐,因为它要求使用maketrans()函数(该函数的作用是把输入字符映射到输出字符)建立一个转换表,然后,再把这个转换表传递给translate()函数。当然,string模块仍然有它自己的maketrans()函数,不过Python 3.1不赞成使用它,而是赞赏使用单独的maketrans()函数来操作字节、字节数组和字符串。

下面的例子演示了如何使用maketrans()和translate()函数处理字节对象。需要注意的是,用于字节的转换表具有256个表项(每一项对应于一个可能的字节),并且这个例子把大部分字节都映射到它们自身,只有1,2和3例外,因为它们分别映射到了4,5和6。如下所示:

>>> tt = bytes.maketrans(b'123', b'456') 
  >>> len(tt) 
  256 
  >>> tt 
  b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\ 
  t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\ 
  x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\ 
  x1e\x1f !"#$%&\'()*+,-./0456456789:;<=> 
  ?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcd 
  efghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\ 
  x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\ 
  x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\ 
  x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\ 
  xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\ 
  xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\ 
  xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\ 
  xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\ 
  xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\ 
  xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\ 
  xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\ 
  xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\ 
  xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\ 
  xfa\xfb\xfc\xfd\xfe\xff'

建好转换表之后,我们只需把它传递给translate()函数即可,如下所示:

>>> b'123456'.translate(tt)

b'456456'我们还可以传递其它的参数作为要删除的字符:

>>> b'123456'.translate(tt, b'5')

b'45646'我们可以看到,原来的5已经从123456从删掉了,但是转换得到的5(请记住,我们的映射表将2转化为5)并没有删除。这说明,系统是先从原来的字符串中删除相应的字符,然后才进行的转换操作。
字符串的转换稍微有些不同,字符串版本的maketrans函数返回的是一个字典:

>>> tt = str.maketrans('123', '456') 
  {49: 52, 50: 53, 51: 54} 
  >>> '123456'.translate(tt) 
  '456456'

四、与数学有关的变化

>>> int.bit_length(19) 
  5 
  >>> bin(19)

3.1版本在与数学有关的方面也有所改变。

Int添加了一个bit_length方法

新版本中,int变量具有一个bit_length方法,它能返回该int变量以二进制数表示的时候的位数。例如,数字19的二进制表示为10011,那么它的位数就是5:

'0b10011'浮点数的舍入

在Python 3.0以及早先的round()函数有点反复无常:如果您不指定精度的时候,它返回的是一个整数;如果指定精度的话,它返回的是您输入数据的类型:

>>> round(1000) 
  1000 
  >>> round(1000.0) 
  1000 
  >>> round(1000, 2) 
  1000 
  >>> round(1000.0, 2)

1000.0在Python 3.1中,只要输入的数字是一个整数(即使它是用浮点数的形式表示的,例如1000.0),那么它总是返回一个整型数:

>>> round(1000) 
  1000 
  >>> round(1000.0) 
  1000 
  >>> round(1000, 2) 
  1000 
  >>> round(1000.0, 2)

1000浮点数的表示

目前,实数在大部分的硬件和操作系统中都是用32位(单精度)或者64位(双精度)来表示的。然而,这会导致一些实数无法精确表示。由于计算机存储器的二进制特性,某些数字利用十进制表示形式非常简洁,但是要是使用浮点方案表示的话,就要复杂了。举例来说,利用32位的单精度浮点数表示数字0.6,则为0.59999999999999998:

>>> 0.6

0.59999999999999998对于这种表示方案,上面的数字是为了做到尽可能的精确,但是对用户来说却很不友好。 Python 3.1使用了一个新算法,以便使得原值的表示尽可能得简练。所以在Python 3.1中,人们输入上面的数字,一个更简洁的表示:

>>> 0.6

0.6这已经很精确了,除非遇到算术运算。举例来说,表达式0.7+0.1的值用32位浮点表示法表示的话,它是 0.79999999999999993,而数字0.8的值用32位浮点数表示则是 0.80000000000000004。 这样一来,就意味着0.7+0.1并不等于0.8,这会导致一些问题。例如,下面的循环将永不休止:

>>> x = 0.0 
  >>> while x != 1.0: 
  ... print(repr(x)) 
  ... x += 0.1输出的结果: 
  0 
  0.10000000000000001 
  0.20000000000000001 
  0.30000000000000004 
  0.40000000000000002 
  0.5 
  0.59999999999999998 
  0.69999999999999996 
  0.79999999999999993 
  0.89999999999999991 
  0.99999999999999989 
  1.0999999999999999 
  1.2 
  1.3 
  1.4000000000000001 
  1.5000000000000002 
  1.6000000000000003

...在Python 3.0中,repr()函数返回的是实际表示;而在Python 3.1中,它返回的是简洁表示。无论是在Python 3.0还是在Python 3.1中,print()函数显示的都是简洁表示:

>>> print(0.1) 
  0.1 
  >>> print(0.10000000000000001)

0.1Python语言还有一个称为decimal的模块,可用于精确的实数表示。它使用一个不同的表示方案来表示浮点数,并且在内存运行的情况下,用尽量多的数位来表示一个实数——并且,当进行算术的时候不会出现舍入误差。在Python 3.0中,Decimal类型使用了一种新方法来从一个字符串初始化它表示的值;在Python 3.1中,又增加了另一个新方法即from_float()来接收浮点数。注意,即使当使用from_float()的时候,Decimal模块也会比32位更精确。

>>> from decimal import Decimal 
  >>> Decimal.from_float(0.1) 
  Decimal('0.1000000000000000055511151231257827021181583404541015625')

五、改进的WITH语句

在Python 2.5中,WITH语句是作为一个__future__特性引入的,该语句的正式引入实际上是从Python 3.0开始的。到了Python 3.1版本,该语句已经能够支持更多的资源。最常见的情形是,它可以打开输入、输出文件并在处理完成后关闭它们。在Python 3.0中,我们要么使用嵌套的with语句,要么显式闭合在文件中。下面是一个Python 3.0的例子,它打开了一个输入文件,将其内容作为字符串读取,用字符串的title()方法处理内容,并将结果写到一个输出文件中。
这个示例中含有两个嵌套的with语句,注意嵌套的with语句中的最后一行。当代码试图读取out.txt的时候,结果为空,因为此文件是被缓冲处理的,并且还没有写入。当此with语句完成的时候,Python会关闭此文件,所以最后一行代码会认定out.txt的内容的确是大写文字。

open('in.txt', 'w').write('abc def') 
  with open('in.txt') as in_file: 
  with open('out.txt', 'w') as out_file: 
  text = in_file.read() 
  assert text == 'abc def' 
  text = text.title() 
  assert text == 'Abc Def' 
  out_file.write(text) 
  assert open('out.txt').read() == ''

assert open('out.txt').read() == 'Abc Def'看到嵌套的with语句,是不是感觉有点头疼,呵呵。接下来,我们要打开两个两个文件,并在处理完成后关闭它们(如果您需要打开三个文件,那么就需要三个嵌套的with语句)。 Python 3.1运行您使用单个WITH语句打开所有文件:

open('in.txt', 'w').write('abc def') 
  with open('in.txt') as in_file: 
  with open('out.txt', 'w') as out_file: 
  text = in_file.read() 
  assert text == 'abc def' 
  text = text.title() 
  assert text == 'Abc Def' 
  out_file.write(text) 
  assert open('out.txt').read() == '' 
  assert open('out.txt').read() == 'Abc Def'

Python 3.1的另一项改进就是,gzip.GzipFile和bz2.BZ2File现在也能用于WITH语句。我们知道,这些都是压缩后的文件格式。下面的示例代码将使用gzip文件和bz2文件来存储5000个字节的内容,并显示其尺寸。这里还有用到一些额外的Python 3特性,比如带有命名属性的统计结果和高级字符串格式化。

from bz2 import BZ2File 
  from gzip import GzipFile 
  import os 
  with GzipFile('1.gz', 'wb') as g, BZ2File('1.bz2', 'wb') as b: 
  g.write(b'X' * 5000) 
  b.write(b'X' * 5000) 
  for ext in ('.gz', '.bz2'): 
  filename = '1' + ext 
  print ('The size of the {0} file is {1.st_size} bytes'.format(ext, os.stat(filename)))输出的结果: 
  The size of the .gz file is 43 bytes 
  The size of the .bz2 file is 45 bytes

六、小结

Python 3.0发布七个月之后,Python核心开发人员于2009年6月27日发布了新的Python 3.1版本。虽然此3.1版本只是对Python 3.0的一次小型升级,但是它不仅为开发者带来许多让人感兴趣的特性,同时在性能方面也有所改善。本文为读者详细介绍了Python 3.1版本在核心语言方面的变化,在接下来的文章中,我们将继续为读者介绍新版本中标准程序库和性能改善方面的变化。

Python 相关文章推荐
Python字符串拼接、截取及替换方法总结分析
Apr 13 Python
numpy使用fromstring创建矩阵的实例
Jun 15 Python
详解Python匿名函数(lambda函数)
Apr 19 Python
使用Python正则表达式操作文本数据的方法
May 14 Python
应用OpenCV和Python进行SIFT算法的实现详解
Aug 21 Python
wxPython电子表格功能wx.grid实例教程
Nov 19 Python
Python求解正态分布置信区间教程
Nov 20 Python
python实现批量处理将图片粘贴到另一张图片上并保存
Dec 12 Python
pytorch中的自定义反向传播,求导实例
Jan 06 Python
Python中requests做接口测试的方法
May 30 Python
用 Python 定义 Schema 并生成 Parquet 文件详情
Sep 25 Python
Elasticsearch 聚合查询和排序
Apr 19 Python
初学Python函数的笔记整理
Apr 07 #Python
利用Python绘制数据的瀑布图的教程
Apr 07 #Python
浅析Python中的多进程与多线程的使用
Apr 07 #Python
Python多线程编程(八):使用Event实现线程间通信
Apr 05 #Python
Python多线程编程(七):使用Condition实现复杂同步
Apr 05 #Python
Python多线程编程(六):可重入锁RLock
Apr 05 #Python
Python多线程编程(五):死锁的形成
Apr 05 #Python
You might like
yii2 在控制器中验证请求参数的使用方法
2019/06/19 PHP
JavaScript与C# Windows应用程序交互方法
2007/06/29 Javascript
jquery focus(fn),blur(fn)方法实例代码
2011/12/16 Javascript
Javascript 面向对象编程(coolshell)
2012/03/18 Javascript
JavaScript中的原型prototype属性使用详解
2015/06/05 Javascript
使用Node.js配合Nginx实现高负载网络
2015/06/28 Javascript
jQuery ajax请求返回list数据动态生成input标签,并把list数据赋值到input标签
2016/03/29 Javascript
JS实用技巧小结(屏蔽错误、div滚动条设置、背景图片位置等)
2016/06/16 Javascript
JS对象创建的几种方式整理
2017/02/28 Javascript
jquery中ajax请求后台数据成功后既不执行success也不执行error的完美解决方法
2017/12/24 jQuery
解决vue中使用swiper插件问题及swiper在vue中的用法
2018/04/04 Javascript
vue仿ios列表左划删除
2019/09/26 Javascript
angular异步验证防抖踩坑实录
2019/12/01 Javascript
vue 使用async写数字动态加载效果案例
2020/07/18 Javascript
js实现双色球效果
2020/08/02 Javascript
python中global与nonlocal比较
2014/11/21 Python
Python中Proxypool库的安装与配置
2018/10/19 Python
Python编程深度学习计算库之numpy
2018/12/28 Python
Python之循环结构
2019/01/15 Python
django rest framework 实现用户登录认证详解
2019/07/29 Python
python pycharm最新版本激活码(永久有效)附python安装教程
2020/09/18 Python
python日期与时间戳的各种转换示例
2020/02/12 Python
python爬取”顶点小说网“《纯阳剑尊》的示例代码
2020/10/16 Python
pytorch学习教程之自定义数据集
2020/11/10 Python
网页切图的CSS和布局经验与要点
2015/04/09 HTML / CSS
新加坡网上化妆品店:Best Buy World
2018/05/18 全球购物
奥地利购买珠宝和手表网站:ELLA JUWELEN
2019/09/03 全球购物
德国排名第一的主题公园门票网站:Attraction Tickets Direct
2019/09/09 全球购物
Contém1g官网:巴西彩妆品牌
2020/01/17 全球购物
初入社会应届生求职信
2013/11/18 职场文书
《猴子种果树》教学反思
2014/04/26 职场文书
物业品质提升方案
2014/06/08 职场文书
工作骂脏话检讨书
2014/10/05 职场文书
怎么写工作检讨书
2014/11/16 职场文书
维稳承诺书
2015/01/20 职场文书
小学美术教学反思
2016/02/17 职场文书