Python3.10の新機能 Python 3.10の新機能(その4) | 演算子によるユニオン型の指定

(その1) パターンマッチ(その2) with文のネスト(その3) エラーメッセージの改善(その4) | 演算子によるユニオン型の指定(その5) パラメータ仕様変数(その6) 明示的な型エイリアス(その7) ユーザ定義型ガード(その8) OpenSSL 1.1.1が必須に(その9) zip()関数に引数 strict を追加(その10) Dataclassでslotsが利用可能に(その11) その他の変更

型ヒント関連では、次の機能がPython 3.10で追加されました。

まず、PEP 604 Allow writing union types as X | Y から解説します。

| 演算子によるユニオン型の指定

Pythonでは、引数にいろいろな種類の値を指定できる関数がめずらしくありません。

例えば、文字列の先頭部分が指定した文字列で始まるかどうかを調べる str.startswith() メソッドには、引数として文字列または文字列のタプルを指定できます。

引数に文字列を指定すると、その文字列で始まる場合には True を返します。

>>> 'abcdefg'.startswith('abc')
True
>>> 'abcdefg'.startswith('123')
False

タプルを指定すると、その中のいずれかの文字列で始まる場合に True を返します。

>>> 'abcdefg'.startswith(('123', 'abc', 'αβγ'))
True

このように、startswith()メソッドの引数には、文字列またはタプルを指定できようになっています。

ユニオン型

この引数のように、異なる型の値を使える変数の型ヒントは ユニオン型 として指定します。startswith()メソッドの引数は、typing.Union を使って、次のように定義できます。

from typing import Union
def startswith(prefix: Union[str, tuple[str, ...]])->bool
   ...

PEP 604: | 演算子によるユニオン型の指定

Pythonではユニオン型がよく使われていますので、いちいち Union をインポートして指定するのは少々面倒でした。

しかし、PEP 604: Allow writing union types as X | Y では、Union を使わなくとも、typescriptなどと同じように | 演算子を使って指定できるようになりました。

def startswith(prefix: str | tuple[str, ...])->bool
   ...

オプショナル型

ところで、startswith()メソッドは、どの文字から比較するか、位置を指定できるようになっています。

開始位置として 3 と指定すると、文字列の3文字目から比較を行います。

>>> 'abc1234'.startswith('abc', 3)
False

開始位置を省略するか、 None を指定すると文字列の先頭から比較を行います。

>>> 'abc1234'.startswith('abc', None)
True

このように、値を指定するか、省略する場合は None を指定する というパターンもPythonではよく使われますので、専用の型定義として Optional が用意されています。Optional を使うと、上記の定義は次のように書けます。

def startswith(prefix:str, start:Optional[int]=None)->bool
   ...

オプショナル型はユニオン型の特殊な場合で、次のように int または None を指定できるユニオン型としても定義できます。

def startswith(prefix:str, start:Union[int, None]=None)->bool
   ...

| 演算子によるオプショナル型の指定

オプショナル型もユニオン型の特殊なケースですので、Python3.10からは同じように | 演算子で書けるようになりました。

def startswith(prefix:str, start:int|None=None)->bool
   ...

isinstance()/issubclass()での利用

従来の typing.Uniontyping.Optional 型は、型アノテーションを指定するためにしか利用できませんでした。 PEP 604 では isinstance()issubclass() にユニオン型を指定できるようになりました。

これまで、オブジェクトが複数の型のどれかに属するかどうかをisinstance() で調べるときには

>>> isintance(obj, (int, str))  # objが整数か文字列のときはTrue
True

とタプルを使って複数の型を指定していました。

今後は | 演算子を使って

>>> isintance(obj, int|str)  # objが整数か文字列のときはTrue
True

と書けるようになりました。

Copyright © 2001-2021 python.jp Privacy Policy python_japan
Amazon.co.jpアソシエイト
Amazonで他のPython書籍を検索