こんにちはPyQチームです。
Python 3.10が10月にリリースされます。Python 3.10にはどんな機能が追加されるのでしょうか?
今回は、Python 3.10の新要素について紹介します。
Python 3.10.0は、2021年7月10日時点でベータ版(beta4)がリリースされています。
正式版までのリリース予定は以下のようになっています。(candidateというのは正式版になる予定のバージョンのことです。candidate後はバグフィックスのみで機能の変更は原則行われないので、candidateでも新機能を試すのには十分です)
- 3.10.0 candidate 1: 2021-08-02(月)
- 3.10.0 candidate 2: 2021-09-06(月) (必要な場合)
- 3.10.0 final: 2021-10-04(月)
Python 3.10のリリーススケジュールについてはPEP619で定義されています。
PEP 619 -- Python 3.10 Release Schedule | Python.org
それではPython 3.10の新要素で代表的な3つを順に見ていきましょう。
Structural Pattern Matching
Python 3.10で追加されたパターンマッチ構文を紹介します。
パターンマッチングの一般的な構文は以下です。
match節に指定したsubjectがcaseのpatternとマッチする場合、指定されたaction(処理)を実行します。
最後の case _:
はif文のelseのようにすべてにマッチするという特別な表現です。
match subject: case <pattern_1>: <action_1> case <pattern_2>: <action_2> case <pattern_3>: <action_3> case _: <action_wildcard>
チュートリアルにある例文を見てみましょう。
以下の例は変数 status
が400, 404, 418, それ以外によって戻り値の文字列を変化させています。
def http_error(status): match status: case 400: return "Bad request" case 404: return "Not found" case 418: return "I'm a teapot" case _: return "Something's wrong with the Internet"
1つの case
で複数の値と比較したい場合は |
を利用できます。
case 401 | 403 | 404: return "Not allowed"
その他、タプル、リストのシーケンス系にもマッチします。
x = [1, 2, 3] match x: case [1]: print("Match 1") case [1, 2]: print("Match 1, 2") case [1, 2, 3]: # <- こことマッチします print("Match 1, 2, 3")
他にも辞書やクラス、Enumなどとマッチします。また、caseの後ろにif節を追加して条件を細かく指定もできます。詳しくは該当のPEPを御覧ください。
- PEP 634 -- Structural Pattern Matching: Specification
- PEP 635 -- Structural Pattern Matching: Motivation and Rationale
- PEP 636 -- Structural Pattern Matching: Tutorial
if ... elif ... elif ...
を繰り返し書いたり、ifの条件式に or 書いて複数条件を指定していたのが楽になりそうですね。
同じ条件分岐をmatch文とif文で書いたものを比較してみましょう。
match文を利用した場合
match status: case 400: return "Bad request" case 401 | 403 | 404: return "Not allowed" case _: return "Something's wrong with the Internet"
if文を利用した場合
if status == 400: return "Bad request" elif status == 401 or status == 403 or status == 404: return "Not allowed" else: return "Something's wrong with the Internet"
特にelif句の部分が見やすくなりました。この部分は elif status in (401, 403, 404):
とも書けます。
Better error messages - SyntaxErrors
構文エラーの表現が改善されました。
括弧を閉じていない場合
括弧を閉じていない場合のエラーの表示が変わりました。 以下のファイルを実行してみましょう。
sample1.py
sample = [1, 2, 3, print("OK")
Python 3.9の場合は、括弧が閉じられていないままファイルの最後になったというエラーでした。
File "/Users/xxxx/sample1.py", line 4 ^ SyntaxError: unexpected EOF while parsing
Python 3.10の場合は、エラーの原因となる括弧の始まりを教えてくれます。
エラーメッセージも「 [
が閉じられていない」というわかりやすい内容に変わっています。
File "/Users/xxxx/sample1.py", line 1 sample = [1, 2, 3, ^ SyntaxError: '[' was never closed
文字リテラルを閉じていない場合
同じように閉じられていない文字リテラルに関するエラーも文字の先頭を示すようになりました。
以下のファイルを実行してみましょう。
sample2.py
sample = "12345678910 print("OK")
Python 3.9
File "/Users/xxxx/sample2.py", line 1 sample = "12345678910 ^ SyntaxError: EOL while scanning string literal
Python 3.10
File "/Users/xxxx/sample2.py", line 1 sample = "12345678910 ^ SyntaxError: unterminated string literal (detected at line 1)
インデントに関するエラーの場合
if文やfor文などのブロックを記述するときにインデントを書き忘れた場合、インデントが必要なブロックの種類を教えてくれるようになりました。
以下のファイルを実行してみましょう。
sample3.py
x = 10 if x: print("OK")
Python 3.9
File "/Users/xxxx/sample3.py", line 3 print("OK") ^ IndentationError: expected an indented block
Python 3.10
File "/Users/xxxx/sample3.py", line 3 print("OK") ^ IndentationError: expected an indented block after 'if' statement on line 2
その他の変更になった構文エラーは以下を参照ください。
型ヒントに関連する新機能
Python 3.5で導入された PEP 484 -- Type Hints に関わる新機能もあります。
PEP 604: New Type Union Operator
PEP 604 で、複数の型の引数を受け入れる型ヒントの書き方が変わりました。typing.Unionを使って指定していた部分に |
演算子が使えるようになりました。
Python 3.9
def square(number: Union[int, float]) -> Union[int, float]: return number ** 2
python 3.10
def square(number: int | float) -> int | float: return number ** 2
他にも型ヒント関連で以下のPEPが採用されました。
- PEP 612, Parameter Specification Variables
- PEP 613, Explicit Type Aliases
- PEP 647: User-Defined Type Guards
その他の変更
Python 3.10では今回紹介した3つの新要素以外にも、既存のモジュールなどの機能がupdateされたり、廃止されたりします。
詳細はPython 3公式ドキュメント - What's New In Python 3.10 をご覧ください。