次のPythonのバージョンである Python 3.12は、2023年10月に正式リリース予定です。
本記事では、Python 3.12の更新内容を紹介します。
- Pythonのリリースについて
- f-strings のPython構文への対応
- TypedDictを使った可変長キーワード引数の型ヒント
- typing.override() デコレーターの追加
- エラーメッセージの改善
- その他の変更点
Pythonのリリースについて
Python 3.12の正式版までのリリーススケジュールはPEP 693で公開され、概ねそのスケジュールに沿って開発が進められています。
2023年7月19日現在の時点では3.12.0 beta 4が公開されており、beta 4以降のスケジュールは以下のとおりです。
- 3.12.0 candidate 1: Monday, 2023-07-31
- 3.12.0 candidate 2: Monday, 2023-09-04
- 3.12.0 final: Monday, 2023-10-02
candidateというのは正式版になる予定のバージョンのことです。 candidate後はバグフィックスのみで機能の変更は原則行われないので、candidateでも新機能を試すのには十分です。
それでは、今回は Python 3公式ドキュメント - What's New In Python 3.12 より、Python 3.12の更新内容を4つ紹介します。
f-strings のPython構文への対応
この機能について、ドキュメントには「Syntactic formalization of f-strings」とあり、直訳すると「f-stringsの構文形式化」です。
「構文形式化」と言われてもよく分かりませんね。
実質的には、この後説明するように「f-strings 中に書ける式がPythonの構文に対応した」という変更です。
Pythonのf-stringsは、「 f""
で囲んだ文字列中の {}
内にPythonの式が書ける」というものですが、Python 3.11までは{}
内に書ける式にいくつか制限がありました。
Python 3.12 ではそれらの制限がなくなり、式がより書きやすくなります。
それでは、どのように変わるのか見ていきましょう。
クォーテーション記号を再利用できる
Python 3.11 ではf""
のように、f-stringsを記述するのに "
で囲んでしまうと、 {}
の中で "
は使えませんでした。
Python 3.12 では、 以下のようにf-strings の囲みに使ったクォーテーション記号を、{}
内でも使えるようになります(Python 3.11 ではSyntaxErrorになります)。
>>> songs = ['Take me back to Eden', 'Alkaline', 'Ascensionism'] >>> f"This is the playlist: {", ".join(songs)}" 'This is the playlist: Take me back to Eden, Alkaline, Ascensionism'
これにより、以下のようにf-stringsを入れ子にすることも可能となります。
>>> f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}" '2'
複数行の式およびコメントが書ける
Python 3.11 では、f-strings の式が複数行になる場合、たとえ結果の文字列が1行だったとしても三連クォーテーションで囲む必要がありました。
そのため、Python 3.11では以下のように書かねばなりません。
>>> f"""This is the playlist: {', '.join([ ... 'Take me back to Eden', ... 'Alkaline', ... 'Ascensionism' ... ])}""" 'This is the playlist: Take me back to Eden, Alkaline, Ascensionism'
また、式が長いとコメントが書きたくなることもありますが、Python 3.11では式内に #
でコメントは書けませんでした。
Python 3.12では、f-strings の式が複数行になる場合でも三連クォーテーションを使う必要がなくなります。また、式内に #
でコメントも記述でき、以下のように書けます。
>>> f"This is the playlist: {', '.join([ ... 'Take me back to Eden', # My, my, those eyes like fire ... 'Alkaline', # Not acid nor alkaline ... 'Ascensionism' # Take to the broken skies at last ... ])}" 'This is the playlist: Take me back to Eden, Alkaline, Ascensionism'
バックスラッシュを書ける
Python 3.11では、f-stringsの式にバックスラッシュ(\
)が書けず、改行文字( "\n"
)などが使えませんでした。
Python 3.12 では、以下のようにf-stringsの式にバックスラッシュ(\
)を書けるようになります(Python 3.11 ではSyntaxErrorになります)。
>>> print(f"This is the playlist: {'\n'.join(songs)}") This is the playlist: Take me back to Eden Alkaline Ascensionism
TypedDictを使った可変長キーワード引数の型ヒント
この機能について、ドキュメントには「Using TypedDict for more precise **kwargs typing」とあります。こちらは型ヒントの書き方についての新機能です。
Pythonの関数やメソッドには、引数名: 型名
で引数に型ヒントを記述できます。
また、引数に**kwargs
と書くことで、引数をキーワード可変長引数にできます。
では以下のように書くと、kwargs
の型はどうなるでしょうか。
def foo(**kwargs: str) -> None: ...
この場合、kwargs
の型は dict[str, str]
と見なされます。
これを踏まえて、TypedDict
を使って以下のようなMovie
型を定義し、Movie
で定義された項目(name
とyear
)を関数の引数に指定したい場合を考えてみましょう。
from typing import TypedDict class Movie(TypedDict): name: str year: int
たとえば以下のように書いてしまうと、kwargs
の型は dict[str, Movie]
と見なされてしまいます。
def foo(**kwargs: Movie) -> None: ...
そこで、Python 3.12では **kwargs: Unpack[Movie]
と書けるようになりました。
from typing import Unpack def foo(**kwargs: Unpack[Movie]): ...
このようにすると、型チェッカーが以下のように判定します。
# 正しい typed_movie: Movie = {"name": "The Meaning of Life", "year": 1983} foo(**typed_movie) # OK! foo(name="The Meaning of Life", year=1983) # OK! # 間違い movie: dict[str, object] = {"name": "Life of Brian", "year": 1979} foo(**movie) # NG!
これにより、関数やメソッドが多くの引数をもつ場合に、その引数をよりシンプルに記述できそうです。
typing.override() デコレーターの追加
この機能について、ドキュメントでは「Override Decorator for Static Typing」とあります。こちらはクラスの継承に関する新機能です。
Python 3.12では、typing モジュールに typing.override()
デコレータが追加されます。
これを使うと、クラスのメソッドがスーパークラスのメソッドをオーバーライドするものであることを、型チェッカーに指定できます。
サンプルは以下のとおりです。
from typing import override class Base: def get_color(self) -> str: return "blue" class GoodChild(Base): @override # OK: Base.get_color をオーバーライド def get_color(self) -> str: return "yellow" class BadChild(Base): @override # 型チェッカーでエラー: Base.get_color をオーバーライドしてない def get_colour(self) -> str: return "red"
これにより、基底クラスのメソッドをオーバーライドするつもりが、実際にはオーバーライドしていなかったというミスを、型チェッカーで発見できるようになります。
エラーメッセージの改善
NameError、SyntaxError、ImportErrorのエラーメッセージが改善されます。
その他の変更点
Python 3.12では今回紹介した4つ以外にも、さまざまな更新があります。
詳細は Python 3公式ドキュメント - What's New In Python 3.12 をご確認ください。