【转】Python 2.7.x 和 Python 3.x 的主要区别

原文链接:http://www.kuqin.com/shuoit/20140728/341451.html

许多 Python 初学者想知道他们应该从 Python 的哪个版本开始学习。对于这个问题我的答案是 “你学习你喜欢的教程的版本,然后检查他们之间的不同。"

但是如果你开始一个新项目,并且有选择权?我想说的是目前没有对错,只要你计划使用的库 Python 2.7.x 和 Python 3.x 双方都支持的话。尽管如此,当在编写它们中的任何一个的代码,或者是你计划移植你的项目的时候,是非常值得看看这两个主要流行的 Python 版本之间的差别的,以便避免常见的陷阱,

章节

future模块

Python 3.x 介绍的 一些Python 2 不兼容的关键字和特性可以通过在 Python 2 的内置__future__模块导入。如果你计划让你的代码支持 Python 3.x,建议你使用__future__模块导入。例如,如果我想要 在Python 2 中表现 Python 3.x 中的整除,我们可以通过如下导入

from __future__ import division

更多的__future__模块可被导入的特性被列在下表中:

feature optional in mandatory in effect
nested_scopes 2.1.0b1 2.2 PEP 227: Statically Nested Scopes
generators 2.2.0a1 2.3 PEP 255: Simple Generators
division 2.2.0a2 3.0 PEP 238: Changing the Division Operator
absolute_import 2.5.0a1 3.0 PEP 328: Imports: Multi-Line and Absolute/Relative
with_statement 2.5.0a1 2.6 PEP 343: The “with” Statement
print_function 2.6.0a2 3.0 PEP 3105: Make print a function
unicode_literals 2.6.0a2 3.0 PEP 3112: Bytes literals in Python 3000

(Source:https://docs.python.org/2/library/future.html)

from platform import python_version

print函数

[跳转到章节预览]

很琐碎,而print语法的变化可能是最广为人知的了,但是仍值得一提的是: Python 2 的print声明已经被print()函数取代了,这意味着我们必须包装我们想打印在小括号中的对象。
Python 2 不具有额外的小括号问题。但对比一下,如果我们按照 Python 2 的方式不使用小括号调用print函数,Python 3 将抛出一个语法异常(SyntaxError)。

Python 2

print ‘Python‘, python_version() print ‘Hello, World!‘ print(‘Hello, World!‘) print "text", ; print ‘print more text on the same line‘
Python 2.7.6 Hello, World! Hello, World! text print more text on the same line

Python 3

print(‘Python‘, python_version()) print(‘Hello, World!‘) print("some text,", end="") print(‘ print more text on the same line‘)
Python 3.4.1 Hello, World! some text, print more text on the same line
print ‘Hello, World!‘
File "", line 1 print ‘Hello, World!‘ ^ SyntaxError: invalid syntax

注意

以上通过 Python 2 使用Printing "Hello, World"是非常正常的,尽管如此,如果你有多个对象在小括号中,我们将创建一个元组,因为print在 Python 2 中是一个声明,而不是一个函数调用。

print ‘Python‘, python_version() print(‘a‘, ‘b‘) print ‘a‘, ‘b‘
Python 2.7.7 (‘a‘, ‘b‘) a b

整除

[跳转到章节预览]

如果你正在移植代码,这个变化是特别危险的。或者你在 Python 2 上执行 Python 3 的代码。因为这个整除的变化表现在它会被忽视(即它不会抛出语法异常)。

因此,我还是倾向于使用一个float(3)/23/2.0代替在我的 Python 3 脚本保存在 Python 2 中的3/2的一些麻烦(并且反而过来也一样,我建议在你的 Python 2 脚本中使用from __future__ import division

Python 2

print ‘Python‘, python_version() print ‘3 / 2 =‘, 3 / 2 print ‘3 // 2 =‘, 3 // 2 print ‘3 / 2.0 =‘, 3 / 2.0 print ‘3 // 2.0 =‘, 3 // 2.0
Python 2.7.6 3 / 2 = 1 3 // 2 = 1 3 / 2.0 = 1.5 3 // 2.0 = 1.0

Python 3

print(‘Python‘, python_version()) print(‘3 / 2 =‘, 3 / 2) print(‘3 // 2 =‘, 3 // 2) print(‘3 / 2.0 =‘, 3 / 2.0) print(‘3 // 2.0 =‘, 3 // 2.0)
Python 3.4.1 3 / 2 = 1.5 3 // 2 = 1 3 / 2.0 = 1.5 3 // 2.0 = 1.0

Unicode

[跳转到章节预览]

Python 2 有ASCII str()类型,unicode()是单独的,不是 byte 类型。

现在, 在 Python 3,我们最终有了Unicode (utf-8)字符串,以及一个字节类:bytebytearrays

Python 2

print ‘Python‘, python_version()
Python 2.7.6
print type(unicode(‘this is like a python3 str type‘))
print type(b‘byte type does not exist‘)
print ‘they are really‘ + b‘ the same‘ they are really the same
print type(bytearray(b‘bytearray oddly does exist though‘))

Python 3

print(‘Python‘, python_version()) print(‘strings are now utf-8 u03BCnicou0394é!‘) Python 3.4.1 strings are now utf-8 μnicoΔé!
print(‘Python‘, python_version(), end="") print(‘ has‘, type(b‘ bytes for storing data‘)) Python 3.4.1 has
print(‘and Python‘, python_version(), end="") print(‘ also has‘, type(bytearray(b‘bytearrays‘))) and Python 3.4.1 also has
‘note that we cannot add a string‘ + b‘bytes for data‘ --------------------------------------------------------------------------- TypeError Traceback (most recent call last) in () ----> 1 ‘note that we cannot add a string‘ + b‘bytes for data‘ TypeError: Can‘t convert ‘bytes‘ object to str implicitly

xrange

[跳转到章节预览]

在 Python 2 中xrange()创建迭代对象的用法是非常流行的。比如: for 循环或者是列表/集合/字典推导式。

这个表现十分像生成器(比如。“惰性求值”)。但是这个xrange-iterable是无穷的,意味着你可以无限遍历。

由于它的惰性求值,如果你不得仅仅不遍历它一次,xrange()函数 比range()更快(比如 for 循环)。尽管如此,对比迭代一次,不建议你重复迭代多次,因为生成器每次都从头开始。

在 Python 3 中,range()是像xrange()那样实现以至于一个专门的xrange()函数都不再存在(在 Python 3 中xrange()会抛出命名异常)。

import timeit n = 10000 def test_range(n): return for i in range(n): pass def test_xrange(n): for i in xrange(n): pass

Python 2

print ‘Python‘, python_version() print ‘ntiming range()‘ %timeit test_range(n) print ‘nntiming xrange()‘ %timeit test_xrange(n) Python 2.7.6 timing range() 1000 loops, best of 3: 433 µs per loop timing xrange() 1000 loops, best of 3: 350 µs per loop

Python 3

print(‘Python‘, python_version()) print(‘ntiming range()‘) %timeit test_range(n) Python 3.4.1 timing range() 1000 loops, best of 3: 520 µs per loop
print(xrange(10)) --------------------------------------------------------------------------- NameError Traceback (most recent call last) in () ----> 1 print(xrange(10)) NameError: name ‘xrange‘ is not defined

Python 3 中的range对象的__contains__方法

另外一件值得一提的事情就是在 Python 3 中range有一个新的__contains__方法(感谢Yuchen Ying指出了这个),__contains__方法可以加速"查找"在 Python 3.x 中显著的整数和布尔类型。

x = 10000000 def val_in_range(x, val): return val in range(x) def val_in_xrange(x, val): return val in xrange(x) print(‘Python‘, python_version()) assert(val_in_range(x, x/2) == True) assert(val_in_range(x, x//2) == True) %timeit val_in_range(x, x/2) %timeit val_in_range(x, x//2) Python 3.4.1 1 loops, best of 3: 742 ms per loop 1000000 loops, best of 3: 1.19 µs per loop

基于以上的timeit的结果,当它使一个整数类型,而不是浮点类型的时候,你可以看到执行查找的速度是 60000 倍快。尽管如此,因为 Python 2.x 的range或者是xrange没有一个__contains__方法,这个整数类型或者是浮点类型的查询速度不会相差太大。

print ‘Python‘, python_version() assert(val_in_xrange(x, x/2.0) == True) assert(val_in_xrange(x, x/2) == True) assert(val_in_range(x, x/2) == True) assert(val_in_range(x, x//2) == True) %timeit val_in_xrange(x, x/2.0) %timeit val_in_xrange(x, x/2) %timeit val_in_range(x, x/2.0) %timeit val_in_range(x, x/2) Python 2.7.7 1 loops, best of 3: 285 ms per loop 1 loops, best of 3: 179 ms per loop 1 loops, best of 3: 658 ms per loop 1 loops, best of 3: 556 ms per loop

下面说下__contain__方法并没有加入到 Python 2.x 中的证据:

print(‘Python‘, python_version()) range.__contains__ Python 3.4.1
print ‘Python‘, python_version() range.__contains__ Python 2.7.7 --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) in () 1 print ‘Python‘, python_version() ----> 2 range.__contains__ AttributeError: ‘builtin_function_or_method‘ object has no attribute ‘__contains__‘
print ‘Python‘, python_version() xrange.__contains__ Python 2.7.7 --------------------------------------------------------------------------- AttributeError Traceback (most recent call last in () 1 print ‘Python‘, python_version() ----> 2 xrange.__contains__ AttributeError: type object ‘xrange‘ has no attribute ‘__contains__‘

**注意在 Python 2 和 Python 3 中速度的不同***

有些猿类指出了 Python 3 的range()和 Python 2 的xrange()之间的速度不同。因为他们是用相同的方法实现的,因此期望相同的速度。尽管如此,这事实在于 Python 3 倾向于比 Python 2 运行的慢一点。

def test_while(): i = 0 while i < 20000: i += 1 return
print(‘Python‘, python_version()) %timeit test_while() Python 3.4.1 100 loops, best of 3: 2.68 ms per loop
print ‘Python‘, python_version() %timeit test_while() Python 2.7.6 1000 loops, best of 3: 1.72 ms per loop

Raising exceptions

[跳转到章节预览]

Python 2 接受新旧两种语法标记,在 Python 3 中如果我不用小括号把异常参数括起来就会阻塞(并且反过来引发一个语法异常)。

Python 2

print ‘Python‘, python_version() Python 2.7.6
raise IOError, "file error" --------------------------------------------------------------------------- IOError Traceback (most recent call last) in () ----> 1 raise IOError, "file error" IOError: file error
raise IOError("file error") --------------------------------------------------------------------------- IOError Traceback (most recent call last) in () ----> 1 raise IOError("file error") IOError: file error

Python 3

print(‘Python‘, python_version()) Python 3.4.1
raise IOError, "file error"
File "", line 1 raise IOError, "file error" ^ SyntaxError: invalid syntax The proper way to raise an exception in Python 3:
print(‘Python‘, python_version()) raise IOError("file error") Python 3.4.1 --------------------------------------------------------------------------- OSError Traceback (most recent call last) in () 1 print(‘Python‘, python_version()) ----> 2 raise IOError("file error") OSError: file error

Handling exceptions

在 Python 3 中处理异常也轻微的改变了,在 Python 3 中我们现在使用as作为关键词。

python 2

print ‘Python‘, python_version() try: let_us_cause_a_NameError except NameError, err: print err, ‘--> our error message‘ Python 2.7.6 name ‘let_us_cause_a_NameError‘ is not defined --> our error message

Python 3

print(‘Python‘, python_version()) try: let_us_cause_a_NameError except NameError as err: print(err, ‘--> our error message‘) Python 3.4.1 name ‘let_us_cause_a_NameError‘ is not defined --> our error message

next() 函数 and .next() 方法

因为next() (.next())是一个如此普通的使用函数(方法),这里有另外一个语法改变(或者是实现上改变了),值得一提的是:在 Python 2.7.5 中函数和方法你都可以使用,next()函数在 Python 3 中一直保留着(调用.next()抛出属性异常)。

Python 2

print ‘Python‘, python_version() my_generator = (letter for letter in ‘abcdefg‘) next(my_generator) my_generator.next()
Python 2.7.6 ‘b‘

Python 3

print(‘Python‘, python_version()) my_generator = (letter for letter in ‘abcdefg‘) next(my_generator)
Python 3.4.1 ‘a‘
my_generator.next()
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) in () ----> 1 my_generator.next() AttributeError: ‘generator‘ object has no attribute ‘next‘

For 循环变量和全局命名空间泄漏

好消息:在 Python 3.x 中 for 循环变量不会再导致命名空间泄漏。

在 Python 3.x 中做了一个改变,在What’s New In Python 3.0中有如下描述:

"列表推导不再支持 [... for var in item1, item2, ...] 这样的语法。使用 [... for var in (item1, item2, ...)] 代替。也需要提醒的是列表推导有不同的语义: 他们关闭了在 `list()` 构造器中的生成器表达式的语法糖, 并且特别是循环控制变量不再泄漏进周围的作用范围域."

Python 2

print ‘Python‘, python_version() i = 1 print ‘before: i =‘, i print ‘comprehension: ‘, [i for i in range(5)] print ‘after: i =‘, i Python 2.7.6 before: i = 1 comprehension: [0, 1, 2, 3, 4] after: i = 4

Python 3

print(‘Python‘, python_version()) i = 1 print(‘before: i =‘, i) print(‘comprehension:‘, [i for i in range(5)]) print(‘after: i =‘, i) Python 3.4.1 before: i = 1 comprehension: [0, 1, 2, 3, 4] after: i = 1

比较不可排序类型

在 Python 3 中的另外一个变化就是当对不可排序类型做比较的时候,会抛出一个类型错误。

Python 2

print ‘Python‘, python_version() print "[1, 2] > ‘foo‘ = ", [1, 2] > ‘foo‘ print "(1, 2) > ‘foo‘ = ", (1, 2) > ‘foo‘ print "[1, 2] > (1, 2) = ", [1, 2] > (1, 2) Python 2.7.6 [1, 2] > ‘foo‘ False (1, 2) > ‘foo‘ = True [1, 2] > (1, 2) = False

Python 3

print(‘Python‘, python_version()) print("[1, 2] > ‘foo‘ = ", [1, 2] > ‘foo‘) print("(1, 2) > ‘foo‘ = ", (1, 2) > ‘foo‘) print("[1, 2] > (1, 2) = ", [1, 2] > (1, 2)) Python 3.4.1 --------------------------------------------------------------------------- TypeError Traceback (most recent call last) in () 1 print(‘Python‘, python_version()) ----> 2 print("[1, 2] > ‘foo‘ = ", [1, 2] > ‘foo‘) 3 print("(1, 2) > ‘foo‘ = ", (1, 2) > ‘foo‘) 4 print("[1, 2] > (1, 2) = ", [1, 2] > (1, 2)) TypeError: unorderable types: list() > str()

通过input()解析用户的输入

幸运的是,在 Python 3 中已经解决了把用户的输入存储为一个str对象的问题。为了避免在 Python 2 中的读取非字符串类型的危险行为,我们不得不使用raw_input()代替。

Python 2

Python 2.7.6 [GCC 4.0.1 (Apple Inc. build 5493)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> my_input = input(‘enter a number: ‘) enter a number: 12 >>> type(my_input) >>> my_input = raw_input(‘enter a number: ‘) enter a number: 123 >>> type(my_input)

Python 3

Python 3.4.1 [GCC 4.2.1 (Apple Inc. build 5577)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> my_input = input(‘enter a number: ‘) enter a number: 12 >>> type(my_input)

返回可迭代对象,而不是列表

如果在 xrange 章节看到的,现在在 Python 3 中一些方法和函数返回迭代对象 -- 代替 Python 2 中的列表

因为我们通常那些遍历只有一次,我认为这个改变对节约内存很有意义。尽管如此,它也是可能的,相对于生成器 --- 如需要遍历多次。它是不那么高效的。

而对于那些情况下,我们真正需要的是列表对象,我们可以通过list()函数简单的把迭代对象转换成一个列表。

Python 2

print ‘Python‘, python_version() print range(3) print type(range(3)) Python 2.7.6 [0, 1, 2]

Python 3

print(‘Python‘, python_version()) print(range(3)) print(type(range(3))) print(list(range(3))) Python 3.4.1 range(0, 3) [0, 1, 2]

在 Python 3 中一些经常使用到的不再返回列表的函数和方法

  • zip()
  • map()
  • filter()
  • dictionary‘s .keys() method
  • dictionary‘s .values() method
  • dictionary‘s .items() method

更多的关于 Python 2 和 Python 3 的文章

下面是我建议后续的关于 Python 2 和 Python 3 的一些好文章。

移植到 Python 3

Python 3 的拥护者和反对者

时间: 2024-11-05 14:53:58

【转】Python 2.7.x 和 Python 3.x 的主要区别的相关文章

【Python&amp;数据结构】 抽象数据类型 Python类机制和异常

这篇是<数据结构与算法Python语言描述>的笔记,但是大头在Python类机制和面向对象编程的说明上面.我也不知道该放什么分类了..总之之前也没怎么认真接触过基于类而不是独立函数的Python编程,借着本次机会仔细学习一下. 抽象数据类型 最开始的计算机语言,关注的都是如何更加有效率地计算,可以说其目的是计算层面的抽象.然而随着这个行业的不断发展,计算机不仅仅用于计算,开发也不仅只关注计算过程了,数据层面的抽象也变得同样重要.虽然计算机语言一开始就有对数据的抽象,但是那些都只是对一些最基本的

代写Python、代做Python、Python作业代写、Python代写(微信leechanx)

代写Python.代做Python.Python作业代写.Python代写(微信leechanx) i++ VS ++i性能区别 i++ 为 function () { tmp = i; i = tmp + 1; return tmp; } ++i 为 function () { i = i + 1; return i; }

Python第一天---第一个Python程序

1.我的环境是windows下,需要安装notepad++,安装Python2,配置环境变量(百度下可以见) 2.打开cmd窗口-----输入I:  [输入要在哪个磁盘存储python代码(我的在I:\pyhtonCode)] ------输入cd PythonCode   [进入PythonCode文件夹] 3.打开I:\pyhtonCode文件夹,在里面新建一个txt文档,取名first.py,右键用nodepad++打开 4.打开文档,输入以下代码: 1 #!/usr/bin/python

[python]自问自答:python -m参数? (转)

python -m xxx.py 作用是:把xxx.py文件当做模块启动但是我一直不明白当做模块启动到底有什么用.python xxx.py和python -m xxx.py有什么区别! 自问自答: python xxx.py python -m xxx.py 这是两种加载py文件的方式:1叫做直接运行2相当于import,叫做当做模块来启动 不同的加载py文件的方式,主要是影响——sys.path 这个属性.sys.path 就相当于liunx中的PATH. 下面来看一下sys.path >>

Python服务器开发一:python基础

Python服务器开发一:python基础 Python(蟒蛇)是一种动态解释型的编程语言.Python可以在Windows.UNIX.MAC等多种操作系统上使用,也可以在Java..NET开发平台上使用. [特点] 1 Python使用C语言开发,但是Python不再有C语言中的指针等复杂的数据类型. 2 Python具有很强的面向对象特性,而且简化了面向对象的实现.它消除了保护类型.抽象类.接口等面向对象的元素. 3 Python代码块使用空格或制表符缩进的方式分隔代码. 4 Python仅

python 调 用另一个python 程序

na = int(input("开奖时间(如:20140630): \n")) import time nb =  int(time.strftime("%Y%m%d")) #获取当前时间的年月日 #print (nb) #获取键盘输入 a = True while a:     if nb < na:         import os         os.system("python shuangseqou.py")         

python安装Fabrix出现Command &quot;python setup.py egg_info&quot;错误

python安装Fabrix出现Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-ynJnAl/pynacl/ 解决: 向上查看发现No package 'libffi' found,原因是这个libffi库未安装 所以使用:yum install libffi-devel -y 最后安装成功

python学习笔记5:python读写文件

python学习笔记5:python读写文件 一.文件的打开模式 1.打开文件 1) f=open('D:\\a.txt','w') 第一个参数是文件的路径,如果只写文件的名字,默认是在当前执行目录下的文件:第二个参数是文件的打开模式 这种方式打开文件,在使用完了之后一定要记得,关闭文件: f.close() 2) with open('D:\\a.txt','w') as f 这种方式打开文件,文件在使用完后会自动关闭文件,不需要close  2. 文件的打开模式 总的来说,文件的打开模式有三

Python自动化开发,Day1 - Python基础1

本章内容 Python是什么? Python的发展史 Python2与3的区别 Python的语言类型 Python的优缺点 一.Python是什么? Python的创始人是吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,在阿姆斯特丹,Guido为了打发圣诞节的无趣,决心开发一个新的脚本解释程序,作为ABC语言的一种继承.之所以选中Python作为该编程语言的名字,是因为他是一个叫Monty Python的喜剧团体的爱好者. 最新的TIOBE排行榜中,Python赶超

python学习之路-1 python简介及安装方法

python简介 一种面向对象.解释型计算机程序设计语言,由Guido van Rossum于1989年发明,第一个公开发行版发行于1991年. 目前最新版本为3.5.1,发布于2015年12月07日. 语法简洁清晰,特色之一是强制用空白符(white space)作为语句缩进. 具有丰富和强大的库,底层是用 C 语言写的,很多标准库和第三方库也都是用 C 写的,运行速度非常快. 极其容易上手,因为Python有极其简单的说明文档. 免费.开源,是FLOSS(自由/开放源码软件)之一.使用者可以