What’s New In Python 3.8 ノート¶
What’s New In Python 3.8 をたどりながら調査。興味のあるものしか読まない。
New Features¶
代入文
:=
ふつうの
=
と微妙に異なる。この演算子は内包記法と相性が良いようだ。
>>> [y for x in range(10) if (y := x**2 - x) > 0] [2, 6, 12, 20, 30, 42, 56, 72]
位置専用引数
引数リストのスラッシュまでが位置専用引数を意味し、キーワード引数のような形では値渡しできない。
この構文は私は使わないだろうが、既存関数のヘルプを参照するときにこの知識が要るわけだ。
>>> help(len) Help on built-in function len in module builtins: len(obj, /) Return the number of items in a container. >>> len(obj=[2,3,4]) TypeError: len() takes no keyword arguments >>> len([2,3,4]) 3
f-string での
=
を用いたオブジェクトの表現中括弧の中に評価したい Python 式に加えて等号を置くと、式を表す文字列がそのまま保たれる機能だ。
次は公式文書からそっくり拝借した利用例だ。
>>> from math import cos, radians >>> theta = 30 >>> f'{theta=} {cos(radians(theta))=:.3f}' 'theta=30 cos(radians(theta))=0.866'
Other Language Changes¶
メソッド
.as_integer_ratio()
float
やdecimal.Decimal
のメソッドだったが、さらにbool
,int
,fractions.Fraction
もこれをサポートするようになった。Fraction
にこれまでサポートされていなかったというのは驚きだ。>>> True.as_integer_ratio() (1, 1) >>> False.as_integer_ratio() (0, 1) >>> (10).as_integer_ratio() (10, 1) >>> (-10).as_integer_ratio() (-10, 1) >>> (0).as_integer_ratio() (0, 1) >>> from fractions import Fraction >>> Fraction(-123, 456).as_integer_ratio() (-41, 152)
正規表現で Unicode の文字名を
\N{name}
の形で書けるようになった。例えば「🀀」にマッチする正規表現は次でもよい:>>> import re >>> text = 'ドラは🀀になりました' >>> re.search(r'\N{MAHJONG TILE EAST WIND}', text) <re.Match object; span=(3, 4), match='🀀'>
逆順サポートが
dict
,dictview
に追加された。使う気がしない。関数
pow(base, exp, mod)
で整数のべき乗の剰余を計算する際に、base
がmod
と互いに素ならばexp
に負の数を許容するようになった。次のコードは公式文書からとってきたものだ:>>> pow(38, -1, 137) 119 >>> 38 * pow(38, -1, 137) % 137 1
これは Diophantus 方程式を解くのに利用できる。これも公式からとってきた例だが、方程式
\[4258x + 147y = 369\]の解を一つ見つけよう。これを次のように書き換えれば:
\[4258x \equiv 369 \pmod{147}\]Python で次のコードで \(x\) および \(y\) を求められることに気づく:
>>> x = 369 * pow(4258, -1, 147) % 147 >>> y = (4258 * x - 369) // -147 >>> 4258 * x + 147 * y 369
dict
の内包表現はキー、値の順に評価される。
New Modules¶
importlib.metadata
このモジュールはサードパーティー製パッケージからバージョン、エントリーポイントなどの諸データを得る機能を提供する。
>>> import importlib.metadata >>> importlib.metadata.version('sympy') '1.5.1' >>> sympy_metadata <email.message.Message at 0x2237c4d4820> >>> list(_) ['Metadata-Version', 'Name', 'Version', 'Summary', 'Home-page', 'Author', 'Author-email', 'License', 'Keywords', 'Platform', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Requires-Python', 'Requires-Dist'] >>> sympy_metadata = importlib.metadata.metadata('sympy') >>> sympy_metadata['Author'] 'SymPy development team' >>> sympy_metadata['Summary'] 'Computer algebra system (CAS) in Python' >>> sympy_metadata['Keywords'] 'Math CAS'
Improved Modules¶
asyncio
¶
Python 3.7 で新設された
run()
が安定 API に昇格した。シェルで python -m asyncio を実行すると、専用対話型インタプリタが起動する。
Windows では、イベントループのデフォルトが
ProactorEventLoop
になった。併せて、ProactorEventLoop
がKeyboardInterrupt
によって中断できるようになった。Task
オブジェクトに名前をつけることができる。生成時にname
を指定するか、メソッドset_name()
を呼べばできる。名前はrepr()
出力やメソッドget_name()
の返り値でわかる。
collections
¶
namedtuple
のメソッド_asdict()
の返り値の型が単なるdict
に変更された。
cProfile
¶
クラス
Profile
がコンテキストマネジャーをサポートした。つまりwith
文でプロファイルがとれる。>>> def fib(n): ... if n == 0: ... return 0 ... elif n == 1: ... return 1 ... else: ... return fib(n - 1) + fib(n - 2) ... >>> from cProfile import Profile >>> with Profile() as profiler: ... for i in range(10): ... print(fib(i)) ... 0 1 1 2 3 5 8 13 21 34 >>> profiler.print_stats() 488 function calls (222 primitive calls) in 0.028 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 276/10 0.000 0.000 0.000 0.000 <ipython-input-107-8190ac52035f>:1(fib) 20 0.000 0.000 0.028 0.001 ansitowin32.py:160(write) 20 0.000 0.000 0.028 0.001 ansitowin32.py:177(write_and_convert) 20 0.000 0.000 0.027 0.001 ansitowin32.py:193(write_plain_text) 20 0.000 0.000 0.000 0.000 ansitowin32.py:245(convert_osc) 20 0.000 0.000 0.028 0.001 ansitowin32.py:40(write) 1 0.000 0.000 0.000 0.000 cProfile.py:133(__exit__) 20 0.000 0.000 0.000 0.000 {built-in method builtins.len} 10 0.000 0.000 0.028 0.003 {built-in method builtins.print} 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 40 0.000 0.000 0.000 0.000 {method 'finditer' of 're.Pattern' objects} 20 0.004 0.000 0.004 0.000 {method 'flush' of '_io.TextIOWrapper' objects} 20 0.023 0.001 0.023 0.001 {method 'write' of '_io.TextIOWrapper' objects}
csv
¶
csv.DictReader
が返す iterable が単なるdict
になった。
datetime
¶
クラスメソッドが二点追加された。これらの逆メソッドはすでにサポート済みだ。
date.fromisocalendar(year, week, day)
datetime.fromisocalendar(year, week, day)
>>> from datetime import date, datetime >>> date.fromisocalendar(2020, 18, 7) datetime.date(2020, 5, 3) >>> datetime.fromisocalendar(2020, 18, 7) datetime.datetime(2020, 5, 3, 0, 0)
functools
¶
lru_cache()
が従来の用法に加えて decorator そのものとしても使えるようになった。>>> from functools import lru_cache >>> @lru_cache ... def fib(n): ... if n == 0: ... return 0 ... elif n == 1: ... return 1 ... else: ... return fib(n - 1) + fib(n - 2) ...
cached_property()
が追加された。一度計算すれば二度と変わらないような値を返すメソッドに適用すると効率が良い。singledispatchmethod()
が追加された。名前からわかるようにsingledispatch()
のメソッド版だ。
itertools
¶
関数
accumulate()
にオプション引数initial
が追加された。
math
¶
関数
dist()
が追加された。Pythagoras の定理に基づく二点間に距離を計算する。
点は iterable で与えることができる。二点の次元は同じであるものとする。
関数
hypot()
の二次元制限が廃止された。関数
prod()
が追加された。組み込み関数sum()
の乗算版だ。関数
perm()
が追加された。順列の数を計算する。関数
comb()
が追加された。二項係数を計算する。関数
isqrt()
が追加された。非負整数を取り非負整数を返す。
os.path
¶
関数のうち、パス文字列を判定して真偽値を返す
exists()
などがValueError
またはそのサブクラスの例外を送出していたような状況において、単にFalse
を返すように変更された。パス文字列が OS レベルで表現できないような文字なりバイトなりを含むときにそうなる。Windows では 関数
expanduser()
が環境変数USERPROFILE
をHOME
よりも優先するようになった。その他の Windows 対応。
pathlib
¶
Path のメソッドのうち、パス文字列を判定して真偽値を返す
exists()
などについてもos.path
での変更と同じものがなされた。
pprint
¶
関数に引数
sort_dicts
が追加された。既定値は True であるが、True と False のどちらも用途があるので考えて使う。
それに伴い関数
pp()
が追加された。sort_dicts=False
として関数pprint()
を呼び出すようなものだ。
statistics
¶
使えるものが相当数追加されている。
関数
fmean()
が追加された。関数mean()
の浮動小数点特化版。関数
geometric_mean()
が追加された。こちらはデータを浮動小数点に変換してから演算する。関数
multimode()
が追加された。最頻値が複数あればそれをすべて返す。関数
quantiles()
が追加された。分割点のほうを返す。キーワード引数
n
で分割数を指定する。既定値は 4 だ。キーワード引数
method
でアルゴリズムを指定する。'inclusive'
か'exclusive'
を指定する。既定値は後者だ。
クラス
NormalDist
が追加された。もちろん正規分布を意味する。コンストラクターから生成するときは期待値と標準偏差を与える。
クラスメソッド
.from_samples()
でデータから生成することもできる。Library Reference の記述がひじょうに丁寧なので読んでおく。
unicodedata
¶
Unicode 12.1.0 に対応。
関数
is_normalized()
が追加された。与えられた文字列が NFC, NFKC, NFD, NFKD 正規形なのかどうかを返す。
以上