kb84tkhrのブログ

何を書こうか考え中です あ、あと組織とは関係ないってやつです 個人的なやつ

PEP 483を読む(続き)

以下、英語のTypeを型と訳すか、タイプとカタカナにするか、
それともTypeのままにしておくか悩ましい感じがしています
型って書くほうが普通かもしれませんがタイプとしてみました

タイプとクラス

Pythonでは、クラスはclass文で定義されたオブジェクトファクトリーであり、type(obj)で返されるものです。クラスは、動的な実行時の概念です。

そうですね

タイプは変数や関数の型アノテーションに現れます。タイプの概念は以下で説明するビルディングブロックで構築され、静的タイプチェッカーで用いられるものです。

クラスとの対比でいうと、実行する前に使うもの、ということね

すべてのクラスはタイプです。

クラスはタイプとして実行前にも使われる
一方タイプは実行時には存在しない、てことかな

PEP484で説明される静的なタイプを、実行時のクラスと混同しないようにしなければなりません。

混同するとどうなる
話が分かりづらくなる、くらいのことかな

  • intはクラスでありタイプである
  • UserID(intのサブクラス)はクラスでありタイプである
  • Union[str, int]はタイプだが真のクラスではない

のでUnion[str, int]のインスタンスを作ることはできません

  • 以下で定義されるタイプ(AnyやUnionなど)はインスタンス化できません。しようとすればTypeErrorが発生します。ただしジェネリックの非抽象サブクラスはインスタンス化できます。
  • 以下で定義されるタイプのサブクラスを作ることはできません。ジェネリックジェネリックから派生するクラスは除きます。
  • これらはすべて、isinstanceやissubclassの中に現れるとTypeErrorを発生します。パラメータなしのジェネリックを除きます。

そういえばそんなことあった

基礎的なビルディングブロック

Any
すべての型はAnyと調和し、Anyはあらゆる型と調和します。

知ってました

Union[t1, t2, ...]
あるタイプがすくなくともt1等のひとつの部分型であれば、この型の部分型です。

t1またはt2または・・・てことね

  • すべてのコンポーネントがt1等の部分型であるUnionはこの型の部分型です。
  • 引数の順序は関係ありません。
  • tiがUnionであれば平滑化されます。Union[int, Union[float, str]]はUnion[int, float, str]です。
  • tiとtjが部分型の関係にあれば、より一般的なほうが残ります。Union[Employee, Manager]はUnion[Employee]です。
  • Union[t1]はt1です。UnionやUnion[()]は不正です。
  • 当然の帰結(Corollary):Union[...,object, ...]はobjectを返します。

そうなるよねって感じ

Corollaryってたぶん、決まりきった訳語があると思うんだけどなんだろう

Callable[[t1,t2, ..., tn], tr]
位置引数t1等を持ち、型trを返す関数です。位置引数はなくてもかまいません。オプショナル引数、キーワード引数やvarargsを指定することはできませんが、Callable[..., tr]として引数リストがチェックされないようにすることはできます。

t1,...tnはカッコに入れなくてもいい気がしないでもない
どっちでもいいけど

返り値の型はどうでもいい、って場合はAnyと書けばいいのかな

Intersection[t1, t2, ...]

へー
あんまり聞き慣れないような
UnionがあればIntersectionもあっていいだろうってとこはありますが

あるタイプがt1等のすべての部分型であれば、この型の部分型です。

当然そういう定義になるね
t1かつt2かつ・・・

  • 引数の順序は関係ありません。入れ子になったintersectionは平滑化されます。Intersection[int, Intersection[float,str]]はIntersection[int, float, str]です。

そうなるのはわかるけど、そういう型ってあるの?
intでありfloatでありstrであるような
なくてもいいわけだけど、ないとすると適切な例と言えるかどうか
ちょっと不健全じゃないか

健全な例ってどんなのかな・・・

Intersection[Union[int, float], Intersection[Union[int, str], Union[int, bool]]]
= Intersection[Union[int, float], Union[int, str], Union[int, bool]]
= Intersection[int]
= int

とか?
ちょっと無理矢理感があるな

引数がひとつだけのintersectionはその引数そのものです。

Intersection[int]はint

引数の間に部分型の関係があれば、より特殊な方が残ります。

Unionとは反対

  • Intersection[t1]はt1です。IntersectionやIntersection[()]は不正です。

()って考えてみると何型?
Tuple[]とおなじ?

当然ですね
(だから「当然の帰結」をあてたのだけど)

IntersectionとUnionの間の相互作用は吹くぜつですが、普通の集合の共通部分(intersection)と和集合(union)がわかっていれば驚くようなことはないでしょう。

これが後で出てくるから、上ではIntersection[float, str]みたいな
例を出すしかなかったのかもしれないな