Python的版本主要分為 2.× 、 3.× 兩個系列。
- Python3計划每年發布一個新的子版本,一次只增加一兩種新語法。
- 使用時當然選擇越新的Python版本越好,版本越老的代碼越難維護。
- 維護老版本的代碼時,需要了解各版本之間的主要差異。有時看到一些代碼的語法特點,可以大致猜出它是什么版本。
Python2與Python3
從Python2到Python3是一個大版本升級,有很多不向下兼容的差異,導致很多Python2的代碼不能被Python3解釋器運行,或者反之。
- Python2的最后一個子版本是Python2.7,此后沒有再發布新版本,只是發布一些維護補丁。
- 到2020年,Python官方將停止對Python2的維護,所有老代碼都會超過保質期。
| 差異點 |
Python2 |
Python3 |
| 輸出方式 |
用print關鍵字,比如print "Hello" |
用print()函數,比如print("Hello") |
| 輸入方式 |
用raw_input()函數 |
用input()函數 |
| 字符串的編碼格式 |
默認采用ASCII |
默認采用Unicode |
| 格式化字符串的方式 |
用 % ,比如"Hello, %s" % ("World") |
用format()函數,比如"Hello, {}".format('World') |
| 源文件的編碼格式 |
默認采用ASCII,因此使用中文時要在源文件開頭加上一行# -*- coding: utf-8 -*- |
默認采用uft-8 |
| … |
… |
… |
Python2系列
Python3系列
Python3.4
增加了標准庫pathlib,用於按面向對象的方式操作文件路徑。如下:
>>> from pathlib import Path
>>> p = Path('/root/test/1.py')
>>> p.name
'1.py'
>>> p.suffix
'.py'
>>> p.exists()
False
增加了標准庫enum,用於定義枚舉類。如下:
>>> from enum import Enum
>>>
>>> class Test(Enum):
... a = 1
... b = 2
... c = 3
...
>>> Test.a
<Test.a: 1>
>>> Test['a'] # 可按名字索引
<Test.a: 1>
>>> list(Test) # 可迭代
[<Test.a: 1>, <Test.b: 2>, <Test.c: 3>]
- 增加了標准庫
asyncio,用於實現異步IO。
- 增加了標准庫
statistics,提供了求平均值、中位數、方差等運算的函數。
- 增加了標准庫
tracemalloc,用於跟蹤內存分配的情況,方便調試。
Python3.5
擴展了迭代拆包運算符 * 、字典拆包運算符 ** 的用法:
可以在元組、列表、集合、字典表達式中使用
>>> *range(4)
SyntaxError: can't use starred expression here
>>> *range(4), 4
(0, 1, 2, 3, 4)
>>> [*range(4), 4]
[0, 1, 2, 3, 4]
>>> {'a': 1, **{'b': 2}}
{'a': 1, 'b': 2}
可以同時使用多次
>>> print(*[1], *[2], *{'c': 3})
1 2 c
>>> dict(**{'a': 1}, **{'b': 2})
{'a': 1, 'b': 2}
允許使用Python2風格的 % 格式化字符串,如下:
>>> '%a' % 3.14
'3.14'
>>> b'%a' % 3.14
b'3.14'
增加了函數注釋的語法,用於說明形參、返回值的類型。
- 它只是注釋,不影響程序運行。
- 它存儲在函數的__annotations__屬性中。
>>> def fun1(a, b: "字符串或None", c: int = 0)-> int:
... pass
...
>>> fun1.__annotations__
{'b': '字符串或None', 'c': <class 'int'>, 'return': <class 'int'>}
增加了用async、await關鍵字定義協程的語法:
async def read_db(db):
data = await db.fetch('SELECT ...')
- 增加了標准庫
zipapp,用於將Python腳本打包成可執行的歸檔文件,后綴名為 .pyz。
Python3.6
可以在數字中插入下划線作為分隔符,提高可讀性。如下:
>>> 1_000_111_000
1000111000
>>> '{:_}'.format(1000000) # 格式化字符串時也可輸出下划線
'1_000_000'
給字符串加上前綴f之后,就會執行花括號 {} 內的語句。如下:
>>> a = 1
>>> f'a={a}'
'a=1'
>>> f'{int(1) + 2}'
'3'
定義元類的更好方法:給類定義__init_subclass__()方法,用於初始化子類。如下:
class TestBase:
subclasses = []
def __init_subclass__(cls, *args, **kwargs):
super().__init_subclass__(*args, **kwargs)
cls.subclasses.append(cls)
- 增加了標准庫
secrets,用於生成安全的隨機數,可用作密碼、加密密鑰。(random模塊生成的隨機數是不安全的哦)
Python3.7
Python3.8
增加了賦值表達式的語法,可以給表達式中的變量賦值。如下:
if a := input(): # a = input(); if a:
print(a)
>>> (a := 0) + 1
1
>>> a
0
定義函數時,在正斜桿 / 之前的參數都會被視作位置參數。如下:
>>> def fun1(a, b, c=0, /, *args, **kwargs):
... pass
...
>>> fun1(1, 2, 3)
>>> fun1(1, 2)
可以在f字符串中用變量=的形式打印變量的值,這在調試時很方便。如下:
>>> x = 1
>>> print(f'{x=}')
x=1
- 可以在finally語句塊中使用continue關鍵字。
- multiprocessing模塊增加了一個SharedMemory類,用於創建進程之間的共享內存。