北京時間 10 月 15 日,Python 官方發佈了 3.8.0 正式版,該版本較 3.7 版本再次帶來了多個很是實用的新特性。html
PEP 572: Assignment Expressionspython
新增一種新語法形式::=
,又稱爲「海象運算符」(爲何叫海象,看看這兩個符號像不像顏表情),若是你用過 Go 語言,應該對這個語法很是熟悉。django
具體做用咱們直接用實例來展現,好比在使用正則匹配時,以往版本中咱們會以下寫:緩存
import re pattern = re.compile('a') data = 'abc' match = pattern.search(data) if match is not None: print(match.group(0))
而使用賦值表達式時,咱們能夠改寫爲:異步
if (match := pattern.search(data)) is not None: print(match.group(0))
在 if 語句中同時完成了求值、賦值變量、變量判斷三步操做,再次簡化了代碼。async
下面是在列表表達式中的用法:函數
filtered_data = [y for x in data if (y := func(x)) is not None]
PEP 570: Python Positional-Only parametersoop
新增一個函數形參標記:/
,用來表示標記左側的參數,都只接受位置參數,不能使用關鍵字參數形式。性能
>>> def pow(x, y, z=None, /): ... r = x ** y ... return r if z is None else r%z ... >>> pow(5, 3) 125 >>> pow(x=5, y=3) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: pow() takes no keyword arguments
這其實是用純 Python 代碼來模擬現有 C 代碼實現的內置函數中相似功能,好比內置函數 len('string')
傳參是不能使用關鍵字參數的。url
PEP 578: Python Runtime Audit Hooks
這讓咱們能夠對某些事件和 API 添加一些鉤子,用於在運行時監聽事件相關的參數。
好比這裏監聽 urllib 請求:
>>> import sys >>> import urllib.request >>> def audit_hook(event, args): ... if event in ['urllib.Request']: ... print(f'{event=} {args=}') ... >>> sys.addaudithook(audit_hook) >>> urllib.request.urlopen('https://httpbin.org/get?a=1') event = 'urllib.Request' args =( 'https://httpbin.org/get?a=1' , None , {}, 'GET' ) <http.client.HTTPResponse object at 0x108f09b38>
官方內置了一些 API,具體可查看 PEP-578 規範文檔,也能夠自定義。
在 Python 3.6 版本中增長了 f-strings,可使用 f 前綴更方便地格式化字符串,同時還能進行計算,好比:
>>> x = 10 >>> print(f'{x+1}') 11
在 3.8 中只須要增長一個 =
符號,便可拼接運算表達式與結果:
>>> x = 10 >>> print(f'{x+1=}') 'x+1=11'
這個特性官方指明瞭適用於 Debug。
在以前版本的 Python 交互模式中(REPL),涉及到 Asyncio 異步函數,一般須要使用 asyncio.run(func())
才能執行。
而在 3.8 版本中,當使用 python -m asyncio
進入交互模式,則再也不須要 asyncio.run
。
>>> import asyncio >>> async def test(): ... await asyncio.sleep(1) ... return 'test' ... >>> await test() 'test'
在 Python 多進程中,不一樣進程之間的通訊是常見的問題,一般的方式是使用 multiprocessing.Queue
或者 multiprocessing.Pipe
,在 3.8 版本中加入了 multiprocessing.shared_memory
,利用專用於共享 Python 基礎對象的內存區域,爲進程通訊提供一個新的選擇。
from multiprocessing import Process from multiprocessing import shared_memory share_nums = shared_memory.ShareableList(range(5)) def work1(nums): for i in range(5): nums[i] += 10 print('work1 nums = %s'% nums) def work2(nums): print('work2 nums = %s'% nums) if __name__ == '__main__': p1 = Process(target=work1, args=(share_nums, )) p1.start() p1.join() p2 = Process(target=work2, args=(share_nums, )) p2.start() # 輸出結果: # work1 nums = [10, 11, 12, 13, 14] # work2 nums = [10, 11, 12, 13, 14]
以上代碼中 work1 與 work2 雖然運行在兩個進程中,但均可以訪問和修改同一個 ShareableList
對象。
熟悉 Python Web 開發的同窗,對 werkzeug.utils.cached_property
與 django.utils.functional.cached_property
這兩個裝飾器必定很是熟悉,它們是內置 @property
裝飾器的增強版,被裝飾的實例方法不只變成了屬性調用,還會自動緩存方法的返回值。
如今官方終於加入了本身的實現:
>>> import time >>> from functools import cached_property >>> class Example: ... @cached_property ... def result(self): ... time.sleep(1) # 模擬計算耗時 ... print('work 1 sec...') ... return 10 ... >>> e = Example() >>> e.result work 1 sec... 10 >>> e.result # 第二次調用直接使用緩存,不會耗時 10
finally:
中如今容許使用 continue
typed_ast
被合併回 CPythonpickle
如今默認使用協議4,提升了性能LOAD_GLOBAL
速度加快了 40%unittest
加入了異步支持ProactorEventLoop
multiprocessing
啓動方法默認使用 spawn
更多具體變化,可查看 What’s New In Python 3.8