python2和python3有啥不一样的?

2021-01-15 09:55发布

4条回答
aijingda
1楼 · 2021-01-15 17:53.采纳回答

按照当前时间点(Python 2.7 和 Python3.6),我从宏观上介绍下Python 3和Python 2的区别,并举一些对应常见的例子哈:

1. 统一了字符编码支持。我特意把它拿出来放在第一条...

2. 增加了新的语法。print/exec等成为了函数,格式化字符串变量,类型标注,添加了nonlocal、yield from、async/await、yield for关键词和__annotations__、__context__、__traceback__、__qualname__等dunder方法。

3. 修改了一些语法。metaclass,raise、map、filter以及dict的items/keys/values方法返回迭代对象而不是列表,描述符协议,保存类属性定义顺序,保存关键字参数顺序

4. 去掉了一些语法。cmp、<>(也就是!=)、xrange(其实就是range)、不再有经典类

5. 增加一些新的模块。concurrent.futures、venv、unittest.mock、asyncio、selectors、typing等

6. 修改了一些模块。主要是对模块添加函数/类/方法(如functools.lru_cache、threading.Barrier)或者参数。

7. 模块改名。把一些相关的模块放进同一个包里面(如httplib, BaseHTTPServer, CGIHTTPServer, SimpleHTTPServer, Cookie, cookielib放进了http里面,urllib, urllib2, urlparse, robotparse放进了urllib里面),个例如SocketServer改成了socketserver,Queue改成queue等

8. 去掉了一些模块或者函数。gopherlib、md5、contextlib.nested、inspect.getmoduleinfo等。去掉的内容的原因主要是2点:1. 过时的技术产物,已经没什么人在用了;2. 出现了新的替代产物后者被证明存在意义不大。理论上对于开发者影响很小。

9. 优化。重新实现了dict可以减少20%-25%的内存使用;提升pickle序列化和反序列化的效率;collections.OrderedDict改用C实现;通过os.scandir对glob模块中的glob()及iglob()进行优化,使得它们现在大概快了3-6倍等.. 这些都是喜大普奔的好消息,同样开发者不需要感知,默默的就会让结果变得更好。

10. 其他。构建过程、C的API、安全性等方面的修改,通常对于开发者不需要关心。

最后,重提一下我经常说的那句话:

Python 2/3的思想基本是共通的,只有少量的语法有差别甚至不兼容。当对Python熟悉到
一定程度时, 即使只会Python 2也可以在很短的时间就能写Python 3的代码。

Python2和Python3分别是Python的两个版本,按照Python官方的计划,Python2只支持到2020年。为了不带入过多的累赘,Python3在设计的时候没有考虑向下相容,许多针对早期Python版本设计的程序都无法在Python3上正常执行。

为了照顾现有程序,Python 2.6作为一个过渡版本,基本使用了Python 2.x的语法和库,同时考虑了向Python 3.0的迁移,允许使用部分Python 3.0的语法与函数。新的Python程序建议使用Python3版本的语法,除非执行环境无法安装Python3或者程序本身使用了不支援Python3的第三方库。目前不支持Python3的第三方库有Twisted, py2exe, PIL等。

Python2与Python3的具体区别如下:

1、print函数

1)在Python 2.6与Python2.7里面,以下三种形式是等价的:

print 'Hello world!'
print ('Hello world!')    # 注意print后面有个空格
print('Hello world!')    # print()不能带有任何其它参数

但在Python3中只能使用后两者,print语句被Python3废弃,只能使用print函数

2)Python 2.6的__future__中实际已经支持了新的print()语法

from __future__ import print_function 
print('Hello', 'world!', sep=' ')

Python3中可以直接使用如下语句:

print('Hello', 'world!', sep=' ')

2、Unicode

Python2中是ASCII编码,需要更改字符集才能正常支持中文,所以在.py文件中会看到

# -*- coding: utf-8 -*-

Python2代码:

>>> str='梦想还是要有的'
>>> str
'\xe6\xa2\xa6\xe6\x83\xb3\xe8\xbf\x98\xe6\x98\xaf\xe8\xa6\x81\xe6\x9c\x89\xe7\x9a\x84'
>>> str=u'梦想还是要有的'
>>> str
u'\u68a6\u60f3\u8fd8\u662f\u8981\u6709\u7684'

Python3中字符串是Unicode (utf-8)编码,支持中文做标识符

>>> str='梦想还是要有的' 
>>> str 
'梦想还是要有的'

由于Python3源码文件默认使用utf-8编码,这就使得以下代码是合法的:

>>> 梦想='dream' 
>>> 梦想 
'dream'

3、除法运算

Python中的除法有两个运算符,/和//

1)/除法

在Python2中/除法规则是整数相除的结果是一个整数,把小数部分完全忽略掉,浮点数除法会保留小数点的部分得到一个浮点数的结果。

>>> 1/2 
0 
>>> 1.0/2.0 
0.5

在Python3中/除法不再这么做了,对于整数之间的相除,结果也会是浮点数。

>>> 1/2 
0.5 
>>> 1.0/2.0 
0.5

2)//除法

对于//除法,这种除法叫做floor除法,会对除法的结果自动进行一个floor操作,在Python2和Python3中是一致的。

4、异常处理

1)Python2中捕获异常的语法为except exc, var,Python3中捕获异常的语法为except exc as var,使用语法except (exc1, exc2) as var可以同时捕获多种类别的异常。 Python 2.6已经支持这两种语法。

2)在Python2时代,所有类型的对象都是可以被直接抛出的,在Python3时代,只有继承自BaseException的对象才可以被抛出。

3)Python2中触发异常可以用raise IOError, "file error"或raise IOError("file error")两种方式,Python3中触发异常只能用raise IOError("file error”)。

4)异常StandardError 被Python3废弃,统一使用Exception

5)在Python2时代,异常在代码中除了表示程序错误,还经常做一些普通控制结构应该做的事情,在Python3中可以看出,设计者让异常变的更加专一,只有在错误发生的情况才能去用异常捕获语句来处理。

5、xrange和range

1)Python3中不再使用xrange方法,只有range方法

2)range在Python2中返回列表,而在Python3中返回range可迭代对象

Python2:

>>> a=range(10) 
>>> print(a) 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Python3:

>>> a=range(10) 
>>> print(a) 
range(0, 10) 
>>> print(list(a)) 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

6、八进制字面量表示

Python3中八进制数必须写成0o777,原来的形式0777不能用了;二进制必须写成0b111。

新增了一个bin()函数用于将一个整数转换成二进制字串。 Python 2.6已经支持这两种语法。

在Python3中,表示八进制字面量的方式只有一种,就是0o1000。

Python2:

>>> 0o1000 
512 
>>> 01000 
512

Python3:

>>> 0o1000 
512 
>>> 01000 
  File "", line 1 
    01000 
        ^ 
SyntaxError: invalid token

7、不等运算符

Python2中不等于有两种写法 != 和 <>

Python3中去掉了<>, 只有!=一种写法

8、去掉了repr表达式``

Python2中反引号``相当于repr函数的作用

Python3中去掉了``这种写法,只允许使用repr函数

9、多个模块被改名(根据PEP8)

StringIO模块现在被合并到新的io模组内。 new, md5, gopherlib等模块被删除。 Python 2.6已经支援新的io模组。

httplib, BaseHTTPServer, CGIHTTPServer, SimpleHTTPServer, Cookie, cookielib被合并到http包内。

取消了exec语句,只剩下exec()函数。 Python 2.6已经支持了exec()函数。

10、数据类型

1)在Python2中long是比int取值范围更大的整数,Python3中取消了long类型,int的取值范围扩大到之前的long类型范围

2)新增了bytes类型,对应于Python2版本的八位串,定义一个bytes字面量的方法如下:

>>> b=b'china' 
>>> type(b) 

3)str 对象和 bytes 对象可以使用 .encode() (str -> bytes) 或 .decode() (bytes -> str)方法相互转化

>>> s=b.decode() 
>>> s 
'china' 
>>> b1=s.encode() 
>>> b1 
b'china'

4)dict的.keys()、.items 和.values()方法返回迭代器,只能通过循环取值,不能通过索引取值,而之前的iterkeys()等函数都被废弃。同时去掉的还有 dict.has_key(),可以用 in来代替

dict={'a':1, 'b':2, 'c':3} 
for key in dict: 
    print(key) 
print('c' in dict)

11、input

在Python2中raw_input()和input( ),两个函数都存在,其中区别为:

1)raw_input():将所有输入作为字符串看待,返回字符串类型

2)input():只能接收"数字"的输入,在对待纯数字输入时具有自己的特性,它返回所输入的数字的类型(int, float )

在Python3中raw_input()和input( )进行了整合,去除了raw_input(),仅保留了input()函数,其接收任意任性输入,将所有输入默认为字符串处理,并返回字符串类型。

12、next()函数和.next()方法

my_generator = (letter for letter in 'abcdefg’)

Python2中可以用 next(my_generator) 和 my_generator.next() 两种方式。

Python3中只能用 next(my_generator)这种方式。

13、列表推导

不再支持[n for n in a,b]语法,改为[n for n in (a,b)]或[n for n in [a,b]]

a=1 
b=2 
c=[n for n in [a,b]] 
print(c)

14、比较符

Python2 中任意两个对象都可以比较,11 < 'test’返回True

Python3中只有同一数据类型的对象可以比较,11 < 'test'报错,需要调用正则判断

import re 
11 < int('test') if re.compile('^[0-9]+$').match('test') else 0

15、打开文件

Python2中使用file( ..... ) 或 open(.....)

Python3中只能使用open(.....)

16、包的定义

Python2:文件夹中必须有_ _ init _ _.py文件

Python3:不需要有_ _ init _ _.py文件

17、map / filter

Python2:返回列表,直接创建值,可以通过索引取值

Python3:返回迭代器,不直接创建值,通过循环,边循环边创建


小小邓
3楼 · 2021-01-19 16:09

>  1. print不再是语句,而是函数,比如原来是 print 'abc' 现在是 print('abc')

但是 python2.6+ 可以使用 from __future__ import print_function 来实现相同功能
>  2. 在Python 3中,没有旧式类,只有新式类,也就是说不用再像这样 class Foobar(object): pass 显式地子类化object
但是最好还是加上. 主要区别在于 old-style 是 classtype 类型而 new-style 是 type类型
>  3. 原来1/2(两个整数相除)结果是0,现在是0.5了
python 2.2+ 以上都可以使用 from __future__ import division 实现改特性, 同时注意 // 取代了之前的 / 运算
>  4. 新的字符串格式化方法format取代%
错误, 从 python2.6+ 开始已经在str和unicode中有该方法, 同时 python3依然支持 % 算符
>  6. xrange重命名为range
同时更改的还有一系列内置函数及方法, 都返回迭代器对象, 而不是列表或者 元组, 比如 filter, map, dict.items 等
>  7. !=取代  <   >  
python2 也很少有人用  <  >  所以不算什么修改
>  8. long重命名为int
不完全对, python3 彻底废弃了 long+int 双整数实现的方法, 统一为 int , 支持高精度整数运算.
>  9. except Exception, e变成except (Exception) as e
只有 python2.5 及以下版本不支持该语法. python2.6 是支持的. 不算新东西
>  10. exec变成函数
类似 print() 的变化, 之前是语句.

简单补充下
* 主要是类库的变化, 组织结构变了些. 但功能没变. urlparse - >  urllib.parse 这样的变化
* 最核心的变化它没有说, 对 bytes 和 原生 UNICODE 字符串的支持, 删除了 unicode 对象, str 为原生 unicode 字符串, bytes 替代了之前的 str 这个是最核心的.
* 其它... 貌似不怎么重要了.


灰机带翅膀
4楼 · 2021-02-26 15:56

1 - print变为print()

从一条语句变为了一个内置函数。

Guido在其谈话“Python Regrets”中说到,将print作为声明会受到诸多限制,使用非常死板。如果将print()作为一个函数,则可添加关键词参数覆写输出参数如分割符或换行符。类似的变化产生在exec()函数上。


2 - 默认为Unicode编码

Python2 的默认编码是 ASCII,这也是导致 Python2 中经常遇到编码问题的原因之一,至于是为什么会使用 ASCII 作为默认编码,原因在于 Python2诞生的时候Unicode已有,但为了兼容Python1依然沿用其设计逻辑。Python 3 使用了文本和(二进制)数据的概念,默认采用了 UTF-8 作为默认编码。


3 - 字符串类型重新指定

在 Python2 中,字符串有两个类型,一个是 unicode,一个是 str,前者表示文本字符串,后者表示字节序列,不过两者并没有明显的界限。在 Python3 中两者做了严格区分,分别用 str 表示字符串,byte 表示字节序列。任何需要写入文本或者网络传输的数据都只接收字节序列,这就从源头上阻止了编码错误的问题。


4 - True和False的关键字化

True 和 False 在 Python2 中是两个全局变量(名字),在数值上分别对应 1 和 0。但既然是变量,那么他们就可以重新赋值而指向其它对象


5 - 整数和除法的更新

单整数类型

Python2中的两种不同的整数类型int和long在Python3 中被彻底统一为int。


除法的修改

在Python2中默认的除法规则是:给定两个整数操作数,“/”执行整数向下除法(去尾,截断小数部分);若其中有至少一个浮点数,则会产生真除法。


6 - 迭代器无所不在

Python3中一个重要的主题是内存保护。使用迭代器比直接在内存中维护整个列表更加有效,尤其是当针对问题对象的目标动作就是迭代时,不必要浪费内存。迭代器的惰性加载特性使得操作大数据更有效率。Python2中的range()和xrange()函数合并成了range(),此外函数map(),filter(),zip()和字典方法keys(),items(),values(),都将返回某种特定类型的迭代器。但使用者若是只是通过返回值进行遍历,则注意不到这些改变。另外,Python2的迭代器必须实现 next 方法,而 Python3 改成了 _ next _ 。


7 - 对模块的修改

新增模块

concurrent.futures、venv、unittest.mock、asyncio、selectors、typing等

修改模块

主要是对模块添加函数/类/方法(如functools.lru_cache、threading.Barrier)或者参数。

模块改名

把一些相关的模块放进同一个包里面(如httplib, BaseHTTPServer, CGIHTTPServer, SimpleHTTPServer, Cookie, cookielib放进了http里面,urllib, urllib2, urlparse, robotparse放进了urllib里面),个例如SocketServer改成了socketserver,Queue改成queue等

删除模块

gopherlib、md5、contextlib.nested、inspect.getmoduleinfo等。去掉的模块基本是过时的而少有人用的技术产物,或是基本被新替代物取代。


相关问题推荐

  • 回答 3

    换行。比如,print hello\nworld效果就是helloworld\n就是一个换行符。\是转义的意思,&#39;\n&#39;是换行,&#39;\t&#39;是tab,&#39;\\&#39;是,\ 是在编写程序中句子太长百,人为换行后加上\但print出来是一整行。...

  • 回答 42

    十种常见排序算法一般分为以下几种:(1)非线性时间比较类排序:a. 交换类排序(快速排序、冒泡排序)b. 插入类排序(简单插入排序、希尔排序)c. 选择类排序(简单选择排序、堆排序)d. 归并排序(二路归并排序、多路归并排序)(2)线性时间非比较类排序:...

  • 回答 70
    已采纳

    前景很好,中国正在产业升级,工业机器人和人工智能方面都会是强烈的热点,而且正好是在3~5年以后的时间。难度,肯定高,要求你有创新的思维能力,高数中的微积分、数列等等必须得非常好,软件编程(基础的应用最广泛的语言:C/C++)必须得很好,微电子(数字电...

  • 回答 28

    迭代器与生成器的区别:(1)生成器:生成器本质上就是一个函数,它记住了上一次返回时在函数体中的位置。对生成器函数的第二次(或第n次)调用,跳转到函数上一次挂起的位置。而且记录了程序执行的上下文。生成器不仅记住了它的数据状态,生成器还记住了程序...

  • 回答 9

    python中title( )属于python中字符串函数,返回’标题化‘的字符串,就是单词的开头为大写,其余为小写

  • 回答 6

    第一种解释:代码中的cnt是count的简称,一种电脑计算机内部的数学函数的名字,在Excel办公软件中计算参数列表中的数字项的个数;在数据库( sq| server或者access )中可以用来统计符合条件的数据条数。函数COUNT在计数时,将把数值型的数字计算进去;但是...

  • 回答 1

    head是方法,所以需要取小括号,即dataset.head()显示的则是前5行。data[:, :-1]和data[:, -1]。另外,如果想通过位置取数据,请使用iloc,即dataset.iloc[:, :-1]和dataset.iloc[:, -1],前者表示的是取所有行,但不包括最后一列的数据,结果是个DataFrame。...

  • Python入门简单吗2021-09-23 13:21
    回答 45

    挺简单的,其实课程内容没有我们想象的那么难、像我之前同学,完全零基础,培训了半年,直接出来就工作了,人家还在北京大公司上班,一个月15k,实力老厉害了

  • 回答 4

    Python针对众多的类型,提供了众多的内建函数来处理(内建是相对于导入import来说的,后面学习到包package时,将会介绍),这些内建函数功用在于其往往可对多种类型对象进行类似的操作,即多种类型对象的共有的操作;如果某种操作只对特殊的某一类对象可行,Pyt...

  • 回答 8

     相当于 ... 这里不是注释

  • 回答 4

    还有FIXME

  • 回答 3

    python的两个库:xlrd和xlutils。 xlrd打开excel,但是打开的excel并不能直接写入数据,需要用xlutils主要是复制一份出来,实现后续的写入功能。

  • 回答 8

    单行注释:Python中的单行注释一般是以#开头的,#右边的文字都会被当做解释说明的内容,不会被当做执行的程序。为了保证代码的可读性,一般会在#后面加一两个空格然后在编写解释内容。示例:#  单行注释print(hello world)注释可以放在代码上面也可以放在代...

  • 回答 2

    主要是按行读取,然后就是写出判断逻辑来勘测行是否为注视行,空行,编码行其他的:import linecachefile=open(&#39;3_2.txt&#39;,&#39;r&#39;)linecount=len(file.readlines())linecache.getline(&#39;3_2.txt&#39;,linecount)这样做的过程中发现一个问题,...

  • 回答 4

    或许是里面有没被注释的代码

  • 回答 26

    自学的话要看个人情况,可以先在B站找一下视频看一下

没有解决我的问题,去提问