python3.8いったい何が更新されましたか.

16989 ワード

2019.10.15日にpython 3.8.0安定版が正式に発表されました.いったいどんな新しい特性と最適化があるのか見てみましょう.
Python 3.8.0安定版の一部の新しい特性:
  • PEP 572、付与式
  • PEP 570、位置パラメータ
  • のみ
  • PEP 587,Python初期化構成(改良埋め込み)
  • PEP 590,Vectorcall:CPython用クイックコールプロトコル
  • PEP 578、運行時審査フック
  • PEP 574、帯域外データのPickleプロトコル5
  • Typing相関(Typing-related):PEP 591,PEP 586およびPEP 589
  • パラレルファイルシステムキャッシュ、コンパイル用バイトコード
  • デバッグバージョンとリリースバージョンの共有ABI
  • typed_astはCPython
  • に統合された.
  • LOAD_GLOBALは現在40%速い
  • pickle現在、プロトコル4がデフォルトで使用され、パフォーマンスが向上しました
  • では、もう少し詳しく見てみましょう.
    PEP 572:Assignment Expressions PEP 572のタイトルはコピー式で[ネーミング式]とも呼ばれていますが、彼は今親切に「海象演算子」(the walrus operator)と呼ばれています.ゾウの目と歯のように生えているから:=2333...
    付与式には多くの用途があり、繰り返し呼び出しを回避し、正規マッチング回数を減らし、whileサイクルで再使用し、リスト解析式のアプリケーションなど...いくつかの公式コードを貼ります.
    if (n := len(a)) > 10:
    	print(f"List is too long ({n} elements, expected <= 10)")
    
    discount = 0.0
    if (mo := re.search(r'(\d+)% discount'), advertisement)):
    	discount = float(mo.group(1)) / 100.0
    
    # Loop over fixed length blocks
    while (block := f.read(256)) != '':
    	process(block)
    
    [clean_name.title() for name in names
    if (clean_name := normalize('NFC', name)) in allowed_names]
    

    Try to limit use of the walrus operator to clean cases that reduce complexity and improve readability.
    海象演算子の使用を制限するには、複雑さを減らし、可読性を向上させる必要があります.
    PEP 570:Positional-only parameters PEP 570は、かつて欠けていたパラメータ伝達方式である.Positional-only parametersは位置パラメータのみである.
    新しい関数パラメータ構文であり、/は、いくつかの関数パラメータがキーワードパラメータとして使用できない位置を指定しなければならないことを示しています.いくつかの公式サイトの例を見てみましょう.
    def f(a, b, /, c, d, *, e, f):
    	print(a, b, c, d, e, f)
    

    有効な呼び出し:
    f(10, 20, 30, d=40, e=50, f=60)
    

    ただし、次はエラーコールです.
    f(10, b=20, c=30, d=40, e=50, f=60)  # b           
    f(10, 20, 30, 40, 50, f=60)  # e         
    

    この表現の一例は、純粋なPython関数が既存のC符号化関数の挙動を完全にシミュレートすることを可能にすることである.たとえば、内蔵pow()関数はキーワードパラメータを受け入れません.
    def pow(x, y, z=None, /):
    	"Emulate the built in pow() function"
    	r = x ** y
    	return r if z is None else r%z
    

    もう1つの例は、パラメータ名がヘルプされていない場合にキーワードパラメータを除外することです.たとえば、レイプlen()関数には署名len(obj,/)があります.これにより、次のような気まずい呼び出しが回避されます.
    len(obj='hello')  # The "obj" keyword agrument impairs readability
    

    パラメータをpositional-onlyとマークするもう一つの利点は、クライアントコードを破壊するリスクがなく、将来パラメータ名を変更できることです.たとえば、統計モジュールでは、パラメータ名distが将来変更される可能性があります.これにより、次の機能の説明が可能になります.
    def quantiles(dist, /, *, n=4, method='exclusive')
    	...
    
    /左側のパラメータはキーワードとして公開されていないため、パラメータ名は**kwargsで使用できます.
    def f(a, b, /, **kwargs):
    	print(a, b, kwargs)
    
    f(10, 20, a=1, b=2, c=3)  # a   b        
    -----
    10 20 {'a': 1, 'b': 2, 'c': 3}
    

    これは,任意のキーワードパラメータを受け入れる必要がある関数と方法の実現を極めて簡略化した.たとえば、collectionsモジュールのコードの抜粋は次のとおりです.
    class Counter(dict):
    	
    	def __init__(self, iterable=None, /, **kwargs):
    		# Note "iterable" is a possible keyword argument
    

    PEP 578:Python Runtime Audit Hooksは、Pythonの実行時に監査フックを追加できるようになりました.
    import sys
    import urllib.request
    
    
    def audit_hook(event, args):
    	if event in ['urllib.Request']:
    		print(f'Network {event=} {args=}')
    	
    sys.addaudithook(audit_hook)
    
    In: urllib.request.urlopen('https://httpbin.org/get?a=1')
    	Network event='urllib.Request' args=('https://httpbin.org/get?a=1', None, {}, 'GET')
    Out: <http.client.HTTPRespinse at 0x10e304310>
    

    現在監査をサポートしている時間名とAPIはPEPドキュメント、urllibを見ることができます.Requestはそのうちの1つです.イベントをカスタマイズすることもできます.
    def audit_hook(event, args):
    	if event in ['make_request']:
    		print(f'Network {event=} {args=}')
    
    In: sys.addaudithook(audit_hook)
    
    In: sys.audit('make_request', 'https://baidu.com')
    Network event = 'make_request' args=('https://baidu.com',)
    
    In: sys.audit('make_request', 'https://douban.com')
    Network event='make_request' args=('https://douban,com',)
    Multiprocessing shared memory
    

    プロセス間で同じメモリ(共有)に直接アクセスできます.
    # IPython   A
    In  : from multiprocessing import shared_memory
    
    In  : a = shared_memory.ShareableList([1, 'a', 0.1])
    
    In  : a
    Out : ShareableList([1, 'a', 0.1], name='psm_d5d6ba1b')  #   name
    # IPython  B(        IPython)
    In  : from multiprocessing import shared_memory
    In  : b = shared_memory.ShareableList(name='psm_d5d6ba1b')
    
    In  : b
    Out : ShareableList([1, 'a', 0.1], name='psm_d5d6ba1b')
    New importlib.metadata module
    

    新しいimportlibを使用するMetadataモジュールは、サードパーティ製パッケージのメタデータを直接読み込むことができます.
    In  : from importlib.metadata import version, files, requires, distribution
    
    In  : version('flask')
    Out : '1.1.1'
    
    In  : requires('requests')
    Out : 
    ['chardet (<3.1.0,>=3.0.2)',
     'idna (<2.9,>=2.5)',
     'urllib3 (!=1.25.0,!=1.25.1,<1.26,>=1.21.1)',
     'certifi (>=2017.4.17)',
     "pyOpenSSL (>=0.14) ; extra == 'security'",
     "cryptography (>=1.3.4) ; extra == 'security'",
     "idna (>=2.0.0) ; extra == 'security'",
     "PySocks (!=1.5.7,>=1.5.6) ; extra == 'socks'",
     'win-inet-pton ; (sys_platform == "win32" and python_version == "2.7") and extra == \'socks\'']
    
    In : dist = distribution('celery')
     
    In : dist.version
    Out: '4.3.0'
     
    In : dist.metadata['Requires-Python']
    Out: '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
     
    In : dist.metadata['License']
     
    In : dist.entry_points
    Out:
    [EntryPoint(name='celery', value='celery.__main__:main', group='console_scripts'),
     EntryPoint(name='celery', value='celery.contrib.pytest', group='pytest11')]
     
    In : files('celery')[8]
    Out: PackagePath('celery/__init__.py')
     
    In : dist.locate_file(files('celery')[8])
    Out: PosixPath('/Users/dongweiming/test/venv/lib/python3.8/site-packages/celery/__init__.py')
    functools.cached_property
    

    キャッシュ・プロパティ(cached_property)は非常に一般的な機能であり、多くの有名なPythonプロジェクトが独自に実現し、ついにバージョン・ライブラリに入りました.
    未完待続...