📚

pythonの数値型と型アノテーション

2022/03/24に公開

整数はint

整数を引数に取る関数はこんなふうにアノテーションしたいだろう。

def f(a: int):
	pass

しかし、整数1int型であるとは限らない。

assert 1 == 1.0 == 1+0j

pythonにおける数の取り扱い

数学的に言えば整数⊂実数⊂複素数だが、pythonの型はそうなっていない。

assert not issubclass(int, float)
assert not issubclass(float, complex)

numbersモジュールに数の抽象基底クラスが定義されている。

from numbers import Complex
assert issubclass(int, Complex)
assert issubclass(float, Complex)
assert issubclass(complex, Complex)

これによりf()はこんな感じでかける。

def f(a: Complex):
	assert a.imag == 0
	a = a.real
	assert float(a).is_integer()
	a = int(a)

型チェッカの扱い

しかし型チェッカは融通がきかない。

f(1)
f(1.0)
f(1+0j)

これは全部mypy, Pylanceでエラーになる。悲しい。
int|float|complexと書くしかないのだろうか?

Discussion