查看原文
其他

5分钟带你了解Python2和3的区别|从此不再纠结

xinxin 菜鸟学Python 2020-11-17

这是菜鸟学Python的第113篇原创文章


阅读本文大概需要5分钟


     下面是一篇来自小密圈的私密分享,小密圈的很多小伙伴问我,关于学Py2.x还是3的问题, 我觉得应该放在公号里面分享一下. 简单说:如果是新手建议直接上3.因为Py3是未来的大势所趋,Py2.7现在只是在维护,不会增加新的功能. 如果是老鸟的话,或者已经上手了Python2的同学,建议继续深入挖掘Py2的技巧和熟练操作.Py2和3的精髓和招式大体相同,其实我一直是2,3混用的,没有感觉到特别大的不适应(除了print)!即使有不同,网上搜一下很快搞定的.说这么多,我还是把2和3的主要区别整理一下给大家,希望能给你一些帮助!




个人的看法:

你在Py2上学了那么长的时候,那么多库和模块你都能掌握.过度到Python3 so easy!而且现在还有2to3的转换神器,让你轻松兼容两套环境!如果非要我说我为啥还一直念念不舍Py2的话,主要还是用习惯了!我自己的电脑上有两套Py2和Py3的环境,一般看我工作的内容进行切换选择.


01

Print


1.Print函数

这个可能是Py2和Py3最大的区别,很多用惯了2的人很不习惯!为啥到3上一定要加一个().因为print 从语句变为函数,我们来看一下Py3中print的源码


我们看一下print的源码,发现*args其实就是你输入的字符串,一个或者多个字符串. 而.sep表示默认用空格区分,而end表示换行,也就是我默认给你换行的


1).py3里面所有额print 都加()

print ("hi","python")

>>hi python #默认sep为空格换行

print ("hi","python",sep="*")

>>hi*python


2).关于换行

py3.x 

print ("hi")

print ("python")

>>

hi

python


print ("hi",end="")

print ("python")

>>hipython


py2.x #用,来表示不换行

print "hi",

print "python"

>>hi python


02

字符串


字符串也就是文本,这个问题一直在py2里面没有很好的处理。在py3里面彻底的解决了。Python 3最重要的改动除了print,大概要算是对文本和二进制数据作了更为清晰的区分。文本总是Unicode,由str类型表示,二进制数据则由bytes类型表示


1).编码问题

Py2.x:里面默认是编码是ASCII,而

import sys

print (sys.getdefaultencoding())

>>ascii


Py3.x:里面默认是utf-8

import sys

print (sys.getdefaultencoding())

>>utf-8


2).字符串类型

py2 :里面的字符串有两种str()类型和unicode类型

s1="大家好"

print type(s1)

>><type 'str'>


s2=u"大家好"

print type(s2)

>><type 'unicode'>


py3:里面的字符串只有一种str()类型,这里的str()类型等价于py3里面的unicode类型

s1="大家好"

print (type(s1))

>>

<class 'str'>


s2=u"大家好"

print (type(s2))

>>

<class 'str'>


3).py3新增bytes类型

s3= b'china'

print (type(s3))

>><class 'bytes'>


这个bytes是什么鬼,为啥要有字节类型,其实主要处理二进制数据.


str对象和bytes对象可以使用encode()/decode()方法相互转化

b=b'python'

print (b)

print (type(b))

>>

b'python'

<class 'bytes'>


s = b.decode()

print (s)

print (type(s))

>>

python

<class 'str'>


b2=s.encode()

print (b2)

print (type(b2))

>>

b'python'

<class 'bytes'>


03

比较判断和除法


1.比较判断

Py2.x:不等运算符用两种!=和<>

Py3.x:里面不等判断只有!=

其实我好像一般不怎么用<>,因为!=打字更快一些,哈哈


2.类型比较

Py2.x:当比较两个变量的时候,比如x<y,如果遇到x和y的类型不匹配,py2直接返回bool结果


感悟:很明显x是列表,而2是整形,二者根本不能比较. py2直接返回False,不严谨!py3对这点改良了


Py3.x:当比较两个变量的时候,比如x<y,如果遇到x和y的类型不匹配,py3直接抛异常


3.除法

Py2.x:整形除法的时候,返回它只取整数部分

print 10/3

>>3


如果要小数必须要在开头加__future__

from __future__ import division

print 10/3

>>3.33333333333


如果只想保留小数点后面2位 

print round(10/3,2)

>>3.33


Py3.x:直接默认在整形数做除法,返回用浮点

print (10/3)

>>3.3333333333333335


print (10//3)

>>3 #//表示取整


print (round(10/3,2))

>>3.33


04

输入函数和可迭代式赋值


1.输入函数  

Py2.x:有两种,获取用户输入的函数

something = input('Enter text: ')

something = raw_input('Enter text: ')


Py3:只有input,删除了raw_input

感悟:看的出Py3里面的input其实就是相当于2里面的raw_input(),名字取input更简洁。后面继续看会发现Py3里面有很多类似的这样的取代.


2.赋值变量,扩展的可迭代解包

py2:

a,b,*res=[1,2,3,4] ,这样写是会报错的

但是py3里面写就合法,这样的写法非常简洁,比如我只想先分析一个列表的头部变量,剩下的我另外处理,用*res就非常方便的切分.

a,b,*res=[1,2,3,4]

print (a)

print (b)

print (res)

>>

1

2

[3, 4]


05

异常处理


Py3里面的异常改动蛮多,总结有3小点:

1).异常的继承

py2.x,所有类型的对象只要发生异常就抛出,不需要继承BaseException

py3.x,只有继承自BaseException的对象才可以被抛出,更加严格规范


2).异常的语法

py2:异常我们有的是可以偷懒写成

try:

10/0

except Exception , e:

print 'error',e


但是在py3里面必须要加上as,不然会报语法错误

try:

    10/0

except Exception as e:

    print ('error',e)

感悟:很明显,py3更注重pythonic风格的编码


3).异常的捕获

py2:里面捕获异常的时候,我们可以raise Exception, args

try:

10/0

except Exception ,e:

raise ValueError,e

>>

    raise ValueError,e

ValueError: integer division or modulo by zero


py3:里面捕获异常的时候,我们必须写成raise Exception(args)

try:

    10/0

except Exception as e:

    raise ValueError(e)

>>

    raise ValueError(e)

ValueError: division by zero

是不是感觉更舒服了更合理了!


06

字典和高阶函数


1.字典

py3.x :字典里面dict.keys(),dict.items()和dict.values()方法返回迭代器

去掉了py2.x里面的iterkeys()

去掉的dict.has_key(),py3.x用in替代它吧 


2.高阶函数

py2.x:zip(),map()和filter()直接返回列表

py3.x:zip(),map()和filter()直接返回迭代器,如果要变列表,必须要加list


py2.x:

s1=[1,2,3]

s2=['a','b','c']

print (zip(s1,s2))

>>[(1, 'a'), (2, 'b'), (3, 'c')]


py3.x:

s1=[1,2,3]

s2=['a','b','c']

print (zip(s1,s2))

>><zip object at 0x00000000027CF788>


print (list(zip(s1,s2)))

>>[(1, 'a'), (2, 'b'), (3, 'c')]

其他的两个高阶函数类似


07

range/xrange


range应该是我们在Python最最常用的网红,Py2和3对它进行的改造

1.Py2.x 

1).range 和xrange都是经常使用的,特别是range()返回一个列表

print range(3)

>>

[0, 1, 2]

2).xrange()一般用来创建迭代对象

print [x for x in xrange(3)]

>>[0, 1, 2]

print list(xrange(3))

>>[0, 1, 2]


2.Py3.x

3).里面xrange()不存在了,只有range().而range()相当于py2.x里面的xrange()

print (range(3))

>>range(0, 3)


想要获取列表,必须要加list 

print (list(range(3)))

>>[0, 1, 2]


感悟:其实主要对内存的节约,py2.x里面比如你range(10000),一下子就生成一个长度为10000的内存空间,而py3的 range(1000)返回的不是列表是一个迭代器,你用的时候一个一个循环取出来,对内存节省很多


08


1.关于类

py2.x:里面子类继承父类经常要写super这个函数,就是子类初始的话要记得初始化父类,这时super()里面要填一些参数


py3.x:里面直接简化了这个过程,省掉super()里面的参数,更简洁更Pythonic


09

生成器函数


py2.x:生成器函数需要生成另外一个生成器生成的值,一般需要嵌套的值


py3.x:增加了一个yield from ,可以简化操作,生成器函数自动把操作交给可以接收到的各个迭代对象处理


10

其他


1).多个模块被改名

_winreg->winreg

ConfigParser->configparser

copy_reg->copyreg

Queue->queue

SocketServer->socketserver

repr->reprlib

其中比较常用的是Queue和SocketServer


2).取消了exec语句

留下了exec()函数.其实py2.7已经开始用exec()函数了.


3.string模块有改动

string.letters

string.lowercase

string.uppercase

上面3个都被移除了,用string.ascii_letters代替

string.ascii_letters.lower()

string.ascii_letters.upper()



结论:


py2和py3最大的区别在print和字符串,其他的都是一些小的修改。但是虽然是小的调整,静心下来思考一下,透过现象看本质。发现py3对语言上更加严谨更严格,可读性更高,代码更简洁更注重安全,越来越Pythonic,处处体现工匠精神,我也衷心希望Python越来越好!


通过上面的分析,如果对py2非常熟悉的同学,上手py3大概只要几个小时.所以千万不要再纠结学py2还是py3,而浪费宝贵的学习时间!



长按二维码,加入小密圈

第二期训练营马上开始

期待你的加入



来源 | 菜鸟学Python

作者 | xinxin

本文章为菜鸟学Python独家原创稿件,未经授权不得转载

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存