详解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开发的单词频率统计工具wordsworth使用方法
Jun 25 Python
Linux上安装Python的PIL和Pillow库处理图片的实例教程
Jun 23 Python
Python开发的实用计算器完整实例
May 10 Python
Python 高级专用类方法的实例详解
Sep 11 Python
Python3.5.3下配置opencv3.2.0的操作方法
Apr 02 Python
解决pandas中读取中文名称的csv文件报错的问题
Jul 04 Python
numpy中loadtxt 的用法详解
Aug 03 Python
django表单的Widgets使用详解
Jul 22 Python
Python 使用 environs 库定义环境变量的方法
Feb 25 Python
python实现打砖块游戏
Feb 25 Python
在django admin中配置搜索域是一个外键时的处理方法
May 20 Python
python rolling regression. 使用 Python 实现滚动回归操作
Jun 08 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
桌面中心(一)创建数据库
2006/10/09 PHP
PHP 函数语法介绍一
2009/06/14 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(二)
2014/06/23 PHP
PHP大转盘中奖概率算法实例
2014/10/21 PHP
smarty实现多级分类的方法
2014/12/05 PHP
PHP递归实现汉诺塔问题的方法示例
2017/11/25 PHP
php遍历目录下文件并按修改时间排序操作示例
2019/07/12 PHP
Yii框架分页技术实例分析
2019/08/30 PHP
jQuery使用手册之 事件处理
2007/03/24 Javascript
javascript 函数调用的对象和方法
2010/07/01 Javascript
onkeydown事件解决按回车键直接提交数据的需求
2013/04/11 Javascript
js 判断计算字符串长度/判断空的简单方法
2013/08/05 Javascript
分享JavaScript获取网页关闭与取消关闭的事件
2013/12/13 Javascript
Bootstrap 最常用的JS插件系列总结(图片轮播、标签切换等)
2016/07/14 Javascript
微信小程序 摇一摇抽奖简单实例实现代码
2017/01/09 Javascript
Angularjs过滤器实现动态搜索与排序功能示例
2017/12/13 Javascript
JavaScript函数apply()和call()用法与异同分析
2018/08/10 Javascript
Node.js一行代码实现静态文件服务器的方法步骤
2019/05/07 Javascript
详解Webpack如何引入CDN链接来优化编译后的体积
2019/06/21 Javascript
js中火星坐标、百度坐标、WGS84坐标转换实现方法示例
2020/03/02 Javascript
浅谈js中的attributes和Attribute的用法与区别
2020/07/16 Javascript
ES6学习教程之Promise用法详解
2020/11/22 Javascript
一些常用的Python爬虫技巧汇总
2016/09/28 Python
Python中%r和%s的详解及区别
2017/03/16 Python
python中的colorlog库使用详解
2019/07/05 Python
详解Python是如何实现issubclass的
2019/07/24 Python
德国宠物用品、宠物食品及水族馆网上商店:ZooRoyal
2017/07/09 全球购物
eDreams意大利:南欧领先的在线旅行社
2018/11/23 全球购物
L*SPACE官网:比基尼、泳装和度假服装
2019/03/18 全球购物
财务分析个人的自荐书范文
2013/11/24 职场文书
大学社团活动策划书
2014/01/26 职场文书
委托书样本
2014/04/02 职场文书
公司董事长助理工作职责
2014/07/12 职场文书
高效笔记技巧分享:学会这些让你不再困扰
2019/09/04 职场文书
Django使用channels + websocket打造在线聊天室
2021/05/20 Python
利用python调用摄像头的实例分析
2021/06/07 Python