扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
python2和python3的区别
10年积累的成都网站制作、成都做网站经验,可以快速应对客户对网站的新想法和需求。提供各种问题对应的解决方案。让选择我们的客户得到更好、更有力的网络服务。我虽然不认识你,你也不认识我。但先网站设计后付款的网站建设流程,更有绥滨免费网站建设让你可以放心的选择与我们合作。
1.性能
Py3.0运行 pystone benchmark的速度比Py2.5慢30%。Guido认为Py3.0有极大的优化空间,在字符串和整形操作上可以取得很好的优化结果。
Py3.1性能比Py2.5慢15%,还有很大的提升空间。
2.编码
Py3.X源码文件默认使用utf-8编码,这就使得以下代码是合法的:
中国 = 'china'
print(中国)
china
3. 语法
1)去除了,全部改用!=
在Python 2里,为了得到一个任意对象的字符串表示,有一种把对象包装在反引号里(比如`x`)的特殊语法。在Python 3里,这种能力仍然存在,但是你不能再使用反引号获得这种字符串表示了。你需要使用全局函数repr()。
Notes
Python 2
Python 3
①
`x` repr(x)
②
`'PapayaWhip' + `2`` repr('PapayaWhip'+ repr(2))
Note:x可以是任何东西 — 一个类,函数,模块,基本数据类型,等等。repr()函数可以使用任何类型的参数。
2)去除``,全部改用repr()
3)关键词加入as 和with,还有True,False,None
4)整型除法返回浮点数,要得到整型结果,请使用//
由于人们常常会忽视Python 3在整数除法上的改动(写错了也不会触发Syntax Error),所以在移植代码或在Python 2中执行Python 3的代码时,需要特别注意这个改动。
所以,我还是会在Python 3的脚本中尝试用float(3)/2或 3/2.0代替3/2,以此来避免代码在Python 2环境下可能导致的错误(或与之相反,在Python 2脚本中用from __future__ import division来使用Python 3的除法)。
Python 2
print '3 / 2 =', 3 / 2 print '3 // 2 =', 3 // 2 print '3 / 2.0 =', 3 / 2.0 print '3 // 2.0 =', 3 // 2.0
3 / 2 = 1 3 // 2 = 1 3 / 2.0 = 1.5 3 // 2.0 = 1.0
默认,如果两个操作数都是整数,Python 2 自动执行整型计算。
Python 3
print('3 / 2 =', 3 / 2) print('3 // 2 =', 3 // 2) print('3 / 2.0 =', 3 / 2.0) print('3 // 2.0 =', 3 // 2.0)
3 / 2 = 1.5 3 // 2 = 1 3 / 2.0 = 1.5 3 // 2.0 = 1.0
Note: 需要注意的是“双划线”(//)操作符将一直执行整除,而不管操作数的类型,这就是为什么 5.0//2.0 值为 2.0。Python 3 中,/ 操作符是做浮点除法,而 // 是做整除(即商没有余数,比如 10 // 3 其结果就为 3,余数会被截除掉,而 (-7) // 3 的结果却是 -3。这个算法与其它很多编程语言不一样,需要注意,它们的整除运算会向0的方向取值。而在 Python 2 中,/ 就是整除,即和 Python 3 中的 // 操作符一样。
5)加入nonlocal语句。使用noclocal x可以直接指派外围(非全局)变量
6)print
去除print语句,加入print()函数实现相同的功能。同样的还有 exec语句,已经改为exec()函数
在Python 2里,print是一个语句。无论你想输出什么,只要将它们放在print关键字后边就可以。
Python 3里,print()是一个函数。就像其他的函数一样,print()需要你将想要输出的东西作为参数传给它。
例如:
2.X: print "The answer is", 2*2
3.X: print("The answer is", 2*2)
2.X: print x, # 使用逗号结尾禁止换行
3.X: print(x, end=" ") # 使用空格代替换行
在Python 2里,如果你使用一个逗号(,)作为print语句的结尾,它将会用空格分隔输出的结果,然后在输出一个尾随的空格(trailing space),而不输出回车(carriage return)。在Python 3里,通过把end=' '作为一个关键字参数传给print()可以实现同样的效果。参数end的默认值为'\n',所以通过重新指定end参数的值,可以取消在末尾输出回车符。
2.X: print # 输出新行
3.X: print() # 输出新行
2.X: print sys.stderr, "fatal error"
3.X: print("fatal error", file=sys.stderr)
在Python 2里,你可以通过使用pipe_name语法,把输出重定向到一个管道,比如sys.stderr。在Python 3里,你可以通过将管道作为关键字参数file的值传递给print()来完成同样的功能。参数file的默认值为std.stdout,所以重新指定它的值将会使print()输出到一个另外一个管道。
2.X: print (x, y) # 输出repr((x, y))
3.X: print((x, y)) # 不同于print(x, y)!
exec语句
exec()函数使用一个包含任意Python代码的字符串作为参数,然后就像执行语句或者表达式一样执行它。exec()跟eval()是相似的,但是exec()更加强大并更具有技巧性。eval()函数只能执行单独一条表达式,但是exec()能够执行多条语句,导入(import),函数声明 — 实际上整个Python程序的字符串表示也可以。
Notes
Python 2
Python 3
①
exec codeString exec(codeString)
②
exec codeString in a_global_namespace exec(codeString, a_global_namespace)
③
exec codeString in a_global_namespace, a_local_namespace exec(codeString, a_global_namespace, a_local_namespace)
在最简单的形式下,因为exec()现在是一个函数,而不是语句,2to3会把这个字符串形式的代码用括号围起来。
Python 2里的exec语句可以指定名字空间,代码将在这个由全局对象组成的私有空间里执行。Python 3也有这样的功能;你只需要把这个名字空间作为第二个参数传递给exec()函数。
更加神奇的是,Python 2里的exec语句还可以指定一个本地名字空间(比如一个函数里声明的变量)。在Python 3里,exec()函数也有这样的功能。
execfile语句
就像以前的exec语句,Python 2里的execfile语句也可以像执行Python代码那样使用字符串。不同的是exec使用字符串,而execfile则使用文件。在Python 3里,execfile语句已经被去掉了。如果你真的想要执行一个文件里的Python代码(但是你不想导入它),你可以通过打开这个文件,读取它的内容,然后调用compile()全局函数强制Python解释器编译代码,然后调用新的exec()函数。
Notes
Python 2
Python 3
execfile('a_filename') exec(compile(open('a_filename').read(),'a_filename','exec'))
7)输入函数改变了,删除了raw_input,用input代替: Python 2有两个全局函数,用来在命令行请求用户输入。第一个叫做input(),它等待用户输入一个Python表达式(然后返回结果)。第二个叫做raw_input(),用户输入什么它就返回什么。这让初学者非常困惑,并且这被广泛地看作是Python语言的一个“肉赘”(wart)。Python 3通过重命名raw_input()为input(),从而切掉了这个肉赘,所以现在的input()就像每个人最初期待的那样工作。
2.X:guess = int(raw_input('Enter an integer : ')) # 读取键盘输入的方法
3.X:guess = int(input('Enter an integer : '))
Note:如果你真的想要请求用户输入一个Python表达式,计算结果,可以通过调用input()函数然后把返回值传递给eval()。
I/O方法xreadlines()
在Python 2里,文件对象有一个xreadlines()方法,它返回一个迭代器,一次读取文件的一行。这在for循环中尤其有用。事实上,后来的Python 2版本给文件对象本身添加了这样的功能。
在Python 3里,xreadlines()方法不再可用了。2to3可以解决简单的情况,但是一些边缘案例则需要人工介入。
Notes
Python 2
Python 3
①
for line in a_file.xreadlines(): for line in a_file:
②
for line in a_file.xreadlines(5): no change (broken)
如果你以前调用没有参数的xreadlines(),2to3会把它转换成文件对象本身。在Python 3里,这种转换后的代码可以完成前同样的工作:一次读取文件的一行,然后执行for循环的循环体。
如果你以前使用一个参数(每次读取的行数)调用xreadlines(),2to3不能为你完成从Python 2到Python 3的转换,你的代码会以这样的方式失败:AttributeError: '_io.TextIOWrapper' object has no attribute 'xreadlines'。你可以手工的把xreadlines()改成readlines()以使代码能在Python 3下工作。(readline()方法在Python 3里返回迭代器,所以它跟Python 2里的xreadlines()效率是不相上下的。)
8)改变了顺序操作符的行为,例如xy,当x和y类型不匹配时抛出TypeError而不是返回随即的 bool值
9)去除元组参数解包。不能def(a, (b, c)):pass这样定义函数了
10)新式的8进制字变量,相应地修改了oct()函数。
2.X的方式如下:
0666
438
oct(438)
'0666'
3.X这样:
0666
SyntaxError: invalid token (pyshell#63, line 1)
0o666
438
oct(438)
'0o666'
11)增加了 2进制字面量和bin()函数
bin(438)
'0b110110110'
_438 = '0b110110110'
_438
'0b110110110'
12)扩展的可迭代解包。在Py3.X 里,a, b, *rest = seq和 *rest, a = seq都是合法的,只要求两点:rest是list对象和seq是可迭代的。
13)新的super(),可以不再给super()传参数,
class C(object):
def __init__(self, a):
print('C', a)
class D(C):
def __init(self, a):
super().__init__(a) # 无参数调用super()
D(8)
C 8
__main__.D object at 0x00D7ED90
14)支持class decorator。用法与函数decorator一样:
def foo(cls_a):
def print_func(self):
print('Hello, world!')
cls_a.print = print_func
return cls_a
@foo
class C(object):
pass
C().print()
Hello, world!
class decorator可以用来玩玩狸猫换太子的大把戏。更多请参阅PEP 3129
4. 字符串和字节串
Python 2有两种字符串类型:Unicode字符串和非Unicode字符串。Python 2有基于ASCII的str()类型,其可通过单独的unicode()函数转成unicode类型,但没有byte类型。
而在Python 3中,终于有了Unicode(utf-8)字符串,以及两个字节类:bytes和bytearrays。Python 3只有一种类型:Unicode字符串(Unicode strings)。只有str一种类型,但它跟2.x版本的unicode几乎一样。
Notes
Python 2
Python 3
①
u'PapayaWhip' 'PapayaWhip'
②
ur'PapayaWhip\foo' r'PapayaWhip\foo'
Python 2里的Unicode字符串在Python 3里即普通字符串,因为在Python 3里字符串总是Unicode形式的。
Unicode原始字符串(raw string)(使用这种字符串,Python不会自动转义反斜线"\")也被替换为普通的字符串,因为在Python 3里,所有原始字符串都是以Unicode编码的。
全局函数unicode()
Python 2有两个全局函数可以把对象强制转换成字符串:unicode()把对象转换成Unicode字符串,还有str()把对象转换为非Unicode字符串。
Python 3只有一种字符串类型,Unicode字符串,所以str()函数即可完成所有的功能。(unicode()函数在Python 3里不再存在了。)
Notes
Python 2
Python 3
unicode(anything) str(anything)
5.数据类型
1)Python 2有为非浮点数准备的int和long类型。int类型的最大值不能超过sys.maxint,而且这个最大值是平台相关的。可以通过在数字的末尾附上一个L来定义长整型,显然,它比int类型表示的数字范围更大。
在Python 3里,只有一种整数类型int,大多数情况下,它很像Python 2里的长整型。
Note:检查一个变量是否是整型,获得它的数据类型,并与一个int类型(不是long)的作比较。你也可以使用isinstance()函数来检查数据类型;再强调一次,使用int,而不是long,来检查整数类型。
sys.maxint
由于长整型和整型被整合在一起了,sys.maxint常量不再精确。但是因为这个值对于检测特定平台的能力还是有用处的,所以它被Python 3保留,并且重命名为sys.maxsize。
Notes
Python 2
Python 3
①
from sys import maxint from sys import maxsize
②
python 2有两个全局函数可以把对象强制转换成字符串:unicode()把对象转换成Unicode字符串,还有str()把对象转换为非Unicode字符串。
python 3只有一个字符串类型,Unicode字符串,所以str()函数即可完成所有的功能。(Unicode()函数在python3 里已经不存在了。)
另外:
没有专门的char()数据类型,确实没有需要有这个类型。
单引号和双引号字符串是完全相同的——他们没有在任何方面不同。
正则表达式,一定要用自然字符串处理正则表达式,否则会需要很多的反斜杠。
使用help(str)可查看字符串对象定义的所有方法及属性。
由于百分号有特殊作用,所以字符串里面要用百分号的话需要使用"%%",如:"select * from my_table where name like '%%测试' "。
你这个是对象里的方法共享变量,不用global.用对象属性就可以了。
数学相关
abs(a) : 求取绝对值。abs(-1)
max(list) : 求取list最大值。max([1,2,3])
min(list) : 求取list最小值。min([1,2,3])
sum(list) : 求取list元素的和。 sum([1,2,3]) 6
sorted(list) : 排序,返回排序后的list。
len(list) : list长度,len([1,2,3])
divmod(a,b): 获取商和余数。 divmod(5,2) (2,1)
pow(a,b) : 获取乘方数。pow(2,3) 8
round(a,b) : 获取指定位数的小数。a代表浮点数,b代表要保留的位数。round(3.1415926,2) 3.14
range(a[,b]) : 生成一个a到b的数组,左闭右开。range(1,10) [1,2,3,4,5,6,7,8,9]
类型转换
int(str) : 转换为int型。int('1') 1
float(int/str) : 将int型或字符型转换为浮点型。float('1') 1.0
str(int) : 转换为字符型。str(1) '1'
bool(int) : 转换为布尔类型。 str(0) False str(None) False
bytes(str,code) : 接收一个字符串,与所要编码的格式,返回一个字节流类型。bytes('abc', 'utf-8') b'abc' bytes(u'爬虫', 'utf-8') b'xe7x88xacxe8x99xab'
list(iterable) : 转换为list。 list((1,2,3)) [1,2,3]
iter(iterable): 返回一个可迭代的对象。 iter([1,2,3]) list_iterator object at 0x0000000003813B00
dict(iterable) : 转换为dict。 dict([('a', 1), ('b', 2), ('c', 3)]) {'a':1, 'b':2, 'c':3}
enumerate(iterable) : 返回一个枚举对象。
tuple(iterable) : 转换为tuple。 tuple([1,2,3]) (1,2,3)
set(iterable) : 转换为set。 set([1,4,2,4,3,5]) {1,2,3,4,5} set({1:'a',2:'b',3:'c'}) {1,2,3}
hex(int) : 转换为16进制。hex(1024) '0x400'
oct(int) : 转换为8进制。 oct(1024) '0o2000'
bin(int) : 转换为2进制。 bin(1024) '0b10000000000'
chr(int) : 转换数字为相应ASCI码字符。 chr(65) 'A'
ord(str) : 转换ASCI字符为相应的数字。 ord('A') 65
相关操作
eval****() : 执行一个表达式,或字符串作为运算。 eval('1+1') 2
exec() : 执行python语句。 exec('print("Python")') Python
filter(func, iterable) : 通过判断函数fun,筛选符合条件的元素。 filter(lambda x: x3, [1,2,3,4,5,6]) filter object at 0x0000000003813828
map(func, *iterable) : 将func用于每个iterable对象。 map(lambda a,b: a+b, [1,2,3,4], [5,6,7]) [6,8,10]
zip(*iterable) : 将iterable分组合并。返回一个zip对象。 list(zip([1,2,3],[4,5,6])) [(1, 4), (2, 5), (3, 6)]
type():返回一个对象的类型。
id(): 返回一个对象的唯一标识值。
hash(object):返回一个对象的hash值,具有相同值的object具有相同的hash值。 hash('python') 7070808359261009780
help():调用系统内置的帮助系统。
isinstance():判断一个对象是否为该类的一个实例。
issubclass():判断一个类是否为另一个类的子类。
globals() : 返回当前全局变量的字典。
next(iterator[, default]) : 接收一个迭代器,返回迭代器中的数值,如果设置了default,则当迭代器中的元素遍历后,输出default内容。
reversed(sequence) : 生成一个反转序列的迭代器。 reversed('abc') ['c','b','a']
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流