python2.7和 python3.4但是不要
很多 Python 刚開始学习的人想知道他们应该从 Python 的哪个版本号開始学习。对于这个问题我的答案是 “你学习你喜欢的教程的版本号。然后检查他们之间的不同。
"
可是假设你開始一个新项目,而且有选择权?我想说的是眼下没有对错,仅仅要你计划使用的库 Python 2.7.x 和 Python 3.x 两方都支持的话。
虽然如此。当在编写它们中的不论什么一个的代码,或者是你计划移植你的项目的时候。是很值得看看这两个主要流行的 Python 版本号之间的区别的,以便避免常见的陷阱。
章节
- 使用
__future__
模块 print
函数- Integer division
- Unicode
- xrange
- Raising exceptions
- Handling exceptions
next()
函数
和.next()
方法- For 循环变量和全局命名空间泄漏
- 比較不可排序类型
- 通过
input()
解析用户的输入 - 返回可迭代对象,而不是列表
- 很多其它的关于 Python 2 和 Python 3 的文章
future模块
Python 3.x 介绍的 一些Python 2 不兼容的keyword和特性能够通过在 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 255: Simple Generators |
division | 2.2.0a2 | 3.0 | PEP 328: Imports: Multi-Line and Absolute/Relative |
with_statement | 2.5.0a1 | 2.6 | PEP 3105: Make print a function |
unicode_literals | 2.6.0a2 | 3.0 | <a rel="nofollow" href="http://legacy.python.org/dev/peps/pep-3112/" """="" target="_blank" style="color: rgb(128, 0, 128); text-decoration: none; outline-style: none;">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 "<ipython-input-3-139a7c5835bd>", 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)/2
或3/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)
字符串,以及一个字节类:byte
和bytearrays
。
Python 2
print 'Python', python_version()
Python 2.7.6
print type(unicode('this is like a python3 str type')) <type 'unicode'>
print type(b'byte type does not exist') <type 'str'>
print 'they are really' + b' the same' they are really the same
print type(bytearray(b'bytearray oddly does exist though')) <type 'bytearray'>
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 <class 'bytes'>
print('and Python', python_version(), end="") print(' also has', type(bytearray(b'bytearrays'))) and Python 3.4.1 also has <class 'bytearray'>
'note that we cannot add a string' + b'bytes for data' ---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-13-d3e8942ccf81> in <module>() ----> 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) <ipython-input-5-5d8f9b79ea70> in <module>() ----> 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 <slot wrapper '__contains__' of 'range' objects>
print 'Python', python_version()
range.__contains__ Python 2.7.7
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-7-05327350dafb> in <module>() 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)
<ipython-input-8-7d1a71bfee8e> in <module>() 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) <ipython-input-8-25f049caebb0> in <module>() ----> 1 raise IOError, "file error" IOError: file error
raise IOError("file error") ---------------------------------------------------------------------------
IOError Traceback (most recent call last)
<ipython-input-9-6f1c43f525b2> in <module>() ----> 1 raise IOError("file error") IOError: file error
Python 3
print('Python', python_version()) Python 3.4.1
raise IOError, "file error"
File "<ipython-input-10-25f049caebb0>", 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) <ipython-input-11-c350544d15da> in <module>() 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) <ipython-input-14-125f388bb61b> in <module>() ----> 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) <ipython-input-16-a9031729f4a0> in <module>() 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: 123 >>> type(my_input)
<type 'int'> >>> my_input = raw_input('enter a number: ') enter a number: 123 >>> type(my_input)
<type 'str'>
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: 123 >>> type(my_input)
<class 'str'>
返回可迭代对象,而不是列表
假设在 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]
<type 'list'>
Python 3
print('Python', python_version()) print(range(3)) print(type(range(3))) print(list(range(3))) Python 3.4.1 range(0, 3) <class 'range'> [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 的拥护者和反对者
10 awesome features of Python that you can't use because you refuse
to upgrade to Python 3Everything you did not want to know about Unicode in Python 3
版权声明:本文博客原创文章,博客,未经同意,不得转载。
python2.7和 python3.4但是不要的更多相关文章
- 烂泥:python2.7和python3.5源码安装
本文由ilanniweb提供友情赞助,首发于烂泥行天下 想要获得更多的文章,可以关注我的微信ilanniweb 前几天在centos6.6安装ansible时,一直提示python版本不对,导致不能安 ...
- python2.7和python3共存
python2.7和python3共存 原本装了python,玩nodejs的时候需要node-gyp来编译依赖,无赖这货需要python2.5<v<3.0,那就弄两个版本吧 转载自 ht ...
- 自动发布工具版本从python2升级成python3后遇到的种种问题(涉及paramiko,Crypto,zipfile等等)
从在公司实习到正式入职,一直还在被同事使用的是我写的一个自动发布工具.该工具的主要功能是:开发人员给出需要更新的代码包(zip格式),测试人员将该代码包部署到测服,这些代码包和JIRA数据库里的项目信 ...
- python2.X和python3.X在同一平台下的切换技巧
python2.X和python3.X在同一平台下的切换技巧 最近在自己的电脑上同时安装了python2.7.11和python3.5.1 在网上搜了一些答案,主要还是参照<learning p ...
- 相比于python2.6,python3.0的新特性。
这篇文章主要介绍了相比于python2.6,python3.0的新特性.更详细的介绍请参见python3.0的文档. Common Stumbling Blocks 本段简单的列出容易使人出错的变动. ...
- python2.x和python3.x的区别
一.python2.x和python3.x中raw_input( )和input( )区别 1.在Python2.x中raw_input( )和input( ),两个函数都存在,其中区别为 raw_i ...
- 在Windows下同时安装Python2.x和Python3.x
前言: Python现在是两个版本共存,Python2.x和Python3.x都同时在更新.但是Python2.x和Python3.x的区别还是很多的(以后我可能会写一篇文章列举一下Python2.x ...
- Windows下python3和python2同时安装python2.exe、python3.exe和pip2、pip3设置
1.添加python2到系统环境变量 打开,控制面板\系统和安全\系统,选择高级系统设置,环境变量,选择Path,点击编辑,新建,分别添加D:\Python\python27和D:\Python\py ...
- 将python2代码转为python3
将python2代码转为python3 1.2to3在anaconda的/bin文件夹下: 2.打印帮助信息 2to3 --help 3.使用2to3 -W [要转换的python2文件目录] 4.转 ...
- [dev][python] 从python2进阶到python3你都需要了解什么
基于python2快速掌握python3 0. 前言 这是一篇road map. 如果你会python2,读完这篇文章之后,你将掌握python3 1. 为什么会出现python3 Why Pytho ...
随机推荐
- Enhancing the Application: Advanced JDBC Features(转)
Enhancing the Application: Advanced JDBC Features This chapter describes additional functionality th ...
- poj 2253 Frogger (最长路中的最短路)
链接:poj 2253 题意:给出青蛙A,B和若干石头的坐标,现青蛙A想到青蛙B那,A可通过随意石头到达B, 问从A到B多条路径中的最长边中的最短距离 分析:这题是最短路的变形,曾经求的是路径总长的最 ...
- java Socket使用详细解释
客户/server通信模式, client需要主动创造和server Socket(套接字), server端收到了client的连接请求, 也会创建与客户连接的 Socket. Socket可看做是 ...
- JavaScript动态更改页面元素
通过JavaScript动态变化HTML元素 至HTML加元 首先需要创建一个标签,然后添加到标签中的相应的内容.然后创建添加到相应的位置好标签. <!DOCTYPE html PUBLIC & ...
- Java 抽象工厂模式
抽象工厂模式(Abstract Factory Pattern)是工厂方法模式的进一步抽象,其英文原话"Provide an interface for creating families ...
- Mahout推荐算法ItemBased
Mahout推荐的ItemBased 一. 算法原理 (一) 基本的 下面的例子,参见图评分矩阵:表现user,归类为item. 图(1) 该算法的原理: 1. 计算Item之间的相似度. ...
- 玩转html5(四)----使用canvas画一个时钟(可以动的哦!)
先给个效果图,我画的比较丑,大家可以自己美化一下, 直接上代码: <!DOCTYPE html> <meta charset="utf-8"> <ht ...
- LayoutInflater使用
在实际工作中,事先写好的布局文件往往不能满足我们的需求,有时会依据情况在代码中自己定义控件,这就须要用到LayoutInflater.LayoutInflater在Android中是“扩展”的意思,作 ...
- 写一个程序,乞讨1+2*2+3*3+n*n值 Java
public static void main(String[] args) { // 1*1+2*2+3*3+n*n int n = 40; // 1 ...
- 使用DbUtils实现CRUD
commons-dbutils 这是 Apache 提供了一个开源组织 JDBC工具库,它是JDBC简包,学习成本低,和使用dbutils可以大大简化jdbc的工作量,同一时候也不会影响程序的性能.因 ...