Python2和Python3的语法区别与兼容写法
真格量化即将上线对Python3的支持。
由于版本间的差异,Python开发者经常需要解决不同版本的兼容问题,除了大家都知道的print是否需要括号,我们来看看还有哪些兼容不同版本的方法和语法差异的注意事项:
一,使用ImportError
Python3中将一些Python2的模块名称做了修改,需要我们做一些处理来保证代码在不同Python版本中能够正常运行。
# -*- coding: utf-8 -*-
try:
# Python3
from configparser import ConfigParser
except ImportError:
# Python2
from ConfigParser import ConfigParser
config = ConfigParser()
# do something
urllib库也是不兼容Python2和Python3的
# -*- coding: utf-8 -*-
try:
# Python2
from urllib import urlencode
from urllib import quote
from urlparse import urlparse
import urllib2 as request
except ImportError:
# Python3
from urllib.parse import urlencode
from urllib.parse import quote
from urllib.parse import urlparse
import urllib.request as request
# do something
二,根据版本来判断
根据sys.version_info.major来判断Python的版本,根据不同的版本导入不同的库。
# -*- coding: utf-8 -*-
import sys
if sys.version_info.major == 2:
# Python2
from urllib import urlencode
from urllib import quote
from urlparse import urlparse
import urllib2 as request
else:
# Python3
from urllib.parse import urlencode
from urllib.parse import quote
from urllib.parse import urlparse
import urllib.request as request
# do something
三、使用脚本将py2代码转为py3
使用命令2to3 -w file.py可以直接在原地修改文件。其他命令可以使用2to3 --help查看;2to3 file.py可以看到转变前后的内容对比
2to3是Python自带的一个代码转换工具,可以将python2的代码自动转换为python3的代码。当然,不幸的是转换出的代码并没有对Python2的兼容做任何的处理。所以我们并不真正使用2to3转换出的代码。不过我们可以执行
2to3 file.py 查看输出信息,并修正相关问题。
四、使用python -3执行Python程序
2to3 可以检查出很多Python2&3的兼容性问题,但也有很多问题是2to3发现不了的。在加上 -3 参数后,程序在运行时会在控制台上将Python2和Python3不一致,同时2to3无法处理的问题提示出来。比如Python3和Python2中对除法的处理规则做过改变。使用-3参数执行4/2将提示 DeprecationWarning: classic int division 。
python -3 file.py
五、使用__future__导入
使用Python3的print函数,禁用Python2的print语句:from __future__ import print_function
像Python3一样,int除以int得float,而不像Python2那样是整除:from __future__ import division
像Python3一样,字符串字面量的类型为文本(Python2中的unicode,Python3中的str),而不是字节(Python2中的str,Python3中的bytes)
from __future__ import unicode_literal
Python2和Python3的print也有不同。print在Python2中是个关键字,而在Python3中是个函数。
在Python2中:
在Python3中:
还有:
六、注意列表推导式的变量作用域
在Python2中,列表推导式中的索引变量的是可以泄露到其封闭作用域中的。而Python3中则不可以。
下面举一个简单的例子说明这个问题,如我们在一个for循环内部使用列表推导式:
for i in range(2):
a = [i for i in range(5)]
print(i)
在Python3中,上面的代码输出为
>>0
>>1
而在Python2中,上面的代码输出为
>>4
>>4
七,除法的区别
Python中除法有两种运算符:’/’和’//’;有三种类型的除法:传统除法、Floor除法和真除法。
X / Y类型:
在Python2.6或者之前,这个操作对于整数运算会省去小数部分,而对于浮点数运算会保持小数部分;在Python3.0中变成真除法(无论任何类型都会保持小数部分,即使整除也会表示为浮点数形式)。
示例代码:
>>>3//2
1
>>>3//2.0
1.0
>>>4//2
2
>>>4//2.0
2.0
Python 3.4版本中结果:
>>>3/2
1.5
>>>3/2.0
1.5
>>>4/2
2.0
>>>4/2.0
2.0
X // Y 类型:
Floor除法:在Python 2.2中新增的操作,在Python2.6和Python3.0中均能使用,这个操作不考虑操作对象的类型,总是省略小数部分,剩下最小的能整除的整数部分。
示例代码:
Python 2.7版本中结果:
>>>3//2
1
>>>3//2.0
1.0
>>>4//2
2
>>>4//2.0
2.0
Python 3.4版本中结果(与2.7版本一样):
>>>3//2
1
>>>3//2.0
1.0
>>>4//2
2
>>>4//2.0
2.0
概括来讲:在Python 2.6中,’/’执行传统除法,如果操作数都是整数的话,执行截断的整数除法(即对于结果只保留整数部分),否则,执行浮点除法(保留余数);’//’执行Floor除法,与Python3.0一样,对于整数执行截断除法,浮点数执行浮点除法。在Python 3.0中,’/’总是执行真除法,不管操作数的类型,都会返回包含任何余数的浮点结果;’//’执行Floor除法,截除掉余数并且针对整数操作数返回一个整数,如果有任何一个操作数是浮点数,则返回一个浮点数。
八,Unicode
Python 2有两种字符串类型:str和unicode,Python 3中的字符串默认就是Unicode,Python 3中的str相当于Python
2中的unicode。
在Python 2中,如果代码中包含非英文字符,需要在代码文件的最开始声明编码,如下
# -*- coding: utf-8 -*-
在Python 3中,默认的字符串就是Unicode,就省去了这个麻烦,下面的代码在Python 3可以正常地运行
a = "汉字"
print(a)
九,has_key
Python 3中的字典不再支持has_key方法
Python 2
person = {"age": 30, "name":
"Xiao Wang"}
print "person has key \"age\": ",
person.has_key("age")
print "person has key \"age\": ",
"age" in person
输出
person has key "age": True
person has key "age": True
Python 3
person = {"age": 30, "name":
"Xiao Wang"}
print("person has key \"age\": ",
"age" in person)
输出
person has key "age": True
print("person has key \"age\": ",
person.has_key("age"))
输出
Traceback (most recent call last):
File
"<stdin>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'has_key'
十 异常处理
Python 2中捕获异常一般用下面的语法
try:
1/0
except ZeroDivisionError, e:
print str(e)
或者
try:
1/0
except ZeroDivisionError as e:
print str(e)
Python 3中不再支持前一种语法,必须使用as关键字。
十一 xrange
Python 2中有 range 和 xrange 两个方法。其区别在于,range返回一个list,在被调用的时候即返回整个序列;
xrange返回一个iterator,在每次循环中生成序列的下一个数字。
Python 3中不再支持 xrange 方法,Python 3中的 range 方法就相当于 Python 2中的 xrange 方法。
十二 map函数
在Python 2中,map函数返回list,而在Python
3中,map函数返回iterator。
Python 2
map(lambda x: x+1, range(5))
输出
[1, 2, 3, 4, 5]
Python 3
map(lambda x: x+1, range(5))
输出
<map object at 0x7ff5b103d2b0>
list(map(lambda x: x+1, range(5)))
输出
[1, 2, 3, 4, 5]
filter函数在Python 2和Python 3中也是同样的区别。
什么时候上线呢?还是已经上线了?
有没有股票或期货形态识别的第三方库呀,比如M头,W底等
厉害,终于有Python3了