Python と型ヒント (Type Hints)

Tetsuya Morimoto
Python と型ヒント
2015-10-10 Tetsuya Morimoto
自己紹介
●
森本 哲也
– twitter: @t2y
●
白ヤギコーポレーション所属
– カメリオAPI開発 ( 興味がある方はブースへ )
●
エキスパート Python プログラミング共訳
●
プログラミング言語歴
– Python (3 年 )
– → Java (3 年 )
– → Go ( 半年 )
求人
●
自然言語処理や機械学習の技術を駆使して製品
開発をしたい人募集!
Pythonのパラドックス
●
2004 年 8 月 Paul Graham
– Python を学ぼうとするプログラマーは賢い
●
Python 2.3.4 (2004-05-27): 2.3 の時代
– 新しい言語を学ぶ人たちはプログラミングが好き
であり、仕事に役立つから学ぶわけではない
– 曲解 : 「優秀な Java プログラマーを採用したかっ
たら Python プログラマーを雇えば良い」
●
いまは成り立たない
Python3 のパラドックス
●
2015 年 10 月
– Python3 を現場に導入しようとするプログラマーは
賢い
– Python3 を導入する人たちはプログラミングが好き
であり、現場で役立つから導入するわけではない
– 曲解 : 「優秀な Python プログラマーを採用した
かったら Python3 を現場に導入すれば良い」
●
それっぽい? ( 自己責任で! )
概要
●
背景
– 漸進的型付け→関数アノテーション→ mypy
●
PEP 484 〜型ヒント〜
– 目的
– 型ヒントのために定義された型 (Any, Union, etc)
– ジェネリクス
●
懸念
– 型ヒントの批判、 Typed Clojure の現在
●
展望
– 構造的部分型 (Structual Subtyping) へ
Python3.5
背景
背景 : 漸進的型付け (Gradual Typing)
●
Jeremy Siek 氏と Walid Taha 氏が 2006 年に
考案した型システム
– 静的型付けと動的型付けを組み合わせられる
– 双方の型システムの良いとこ取りしたもの
– Object 型ではなく Any 型を導入しなければならな
い背景の説明
●
PEP 484 の理論的背景
●
入門記事 : 漸進的型付けとは何か
背景 : 関数アノテーション (PEP3017)
●
Python3.0 で導入 (PEP3017)
– 2008-12-03 リリース
– 関数に任意のアノテーションを書く仕組み
●
PEP 484 を支える基本的な仕組み
– 関数アノテーションの用途を型アノテーションに
限定した
– 関数オブジェクトの __annotations__ 属性に保持
されるのは同じ
背景 :mypy プロジェクト (1)
●
http://mypy-lang.org/
●
作者 : Jukka Lehtosalo 氏
– プログラマーを 6 年、マネージャーを 2 年
– 2009 年からケンブリッジ大学の博士課程
●
2012 PyCon Finland
– MYPY: A PYTHON VARIANT WITH SEAMLESS DYNA
MIC AND STATIC TYPING
●
静的型付けと動的型付けの融合
– PyPy や Cython がライバル、 GIL のない VM
背景 :mypy プロジェクト (2)
●
現時点の mypy ができること
– GIL のない VM
– 型アノテーション→ PEP 484 で標準化
– 静的型チェッカーとしての Lint ツール
●
PEP 484 では型チェッカーは提供しない
PEP 484
型ヒント
型ヒント : サンプルコード
# -*- coding: utf-8 -*-
import json
import sys
from pprint import pformat
from typing import Any, Dict
def pretty_format(data: Dict[str, Any]) -> str:
return pformat(data, width=1)
def main() -> None:
raw_data = sys.argv[1] # type: str
data = pretty_format(json.loads(raw_data))
print(data)
data.append('mypy')
main()
$ mypy tutorial.py
tutorial.py: note: In function "main":
tutorial.py:14: error:
"str" has no attribute "append"
型ヒント : 目的
●
型アノテーションの構文を標準化
●
静的解析
– Lint ツール ( オフライン型チェッカー )
●
IDE
– コード補完やリファクタリング機能に利用
– Type Hinting in PyCharm
●
ドキュメンテーション
– 型アノテーションがそのまま使える?
Python は
動的型付け言語
型ヒント :Sphinx
俺がやる!
型ヒント :Any 型
●
全ての型は Any 型のサブタイプ
– object 型と似ているが、型チェッカーによる扱い
が異なる
●
object 型
– 型チェッカーは値のほとんどの操作を拒否する
●
Any 型
– 型チェッカーは値の全ての操作を許容する
any_and_object.py: note: In function "object_func":
any_and_object.py:8: error: Unsupported left operand type
for + ("object")
型ヒント :Any 型と object 型
from typing import Any
def any_func(x: Any, y: Any) -> Any:
return x + y
def object_func(x: object, y: object) -> object:
return x + y
mypy
object 型の操作は型チェカーでエラーとなる
理論的背景は「漸進的型付けとは何か」を参照
型ヒント : 直和型 (Union Type)
●
直和型
– 関数型プログラミング言語でよく使われるデータ型
– 典型的にはツリーのデータ構造を簡潔に表現できる
●
単一の引数に対して少数の期待される型の集合
をとる
e = Union[Employee, Sequence[Employee]]
# OCaml バリアント型
type day = Sun | Mon | Tue | Wed | Thu | Fri | Sat
# 第7回「代数データ型」でいろいろなデータを表してみる
型ヒント :Optional 型
●
直和型の応用
●
Union[T1, None] と Optional[T1] は等価
– None を取り得ることが明示される
– None は多くの操作が型エラー
●
Java の NullPointerException はこりごり
– @Nonnull, @Nullable のアノテーションを明示
– Collections.emptyList(), Collections.emptyMap()
●
Null 安全を型システムで保証する世界へ
型ヒント :Optional 型の例
from typing import Optional, Union
def func1(data: Optional[int]) -> int:
return 3 + data
def func2(data: Union[int, None]) -> int:
return 3 + data
def func3(data: int=None) -> int:
return 3 + data
これらは等価な型ヒント
・デフォルト引数に
None を指定したときも
Optional 型として扱う
TypeError: unsupported operand type(s) for +:
'int' and 'NoneType'
型ヒント : ジェネリクス
●
コンテナー内の要素に期待する型を示す
●
TypeVar というファクトリーを使って型変数を
定義する
from typing import Sequence, TypeVar
T = TypeVar('T') # Declare type variable
def first(l: Sequence[T]) -> T: # Generic function
return l[0]
型ヒント :TypeVar
●
TypeVar のコンストラクタに渡す型変数を表す
文字列と代入する変数名は同じでなければいけ
ない
from typing import TypeVar
X = TypeVar('X') # correct
Z = TypeVar('Y') # error
mypy
generics_typevar.py:4: error: Unexpected TypeVar() argument value
型ヒント :TypeVar の例
●
typing モジュールにいくつか定義されてる
# Some unconstrained type variables. These are used by the container types.
T = TypeVar('T') # Any type.
KT = TypeVar('KT') # Key type.
VT = TypeVar('VT') # Value type.
T_co = TypeVar('T_co', covariant=True) # Any type covariant containers.
V_co = TypeVar('V_co', covariant=True) # Any type covariant containers.
VT_co = TypeVar('VT_co', covariant=True) # Value type covariant containers.
T_contra = TypeVar('T_contra', contravariant=True) # Ditto contravariant.
# A useful type variable with constraints. This represents string types.
# TODO: What about bytearray, memoryview?
AnyStr = TypeVar('AnyStr', bytes, str)
型の別名
型ヒント : 型別名と直和型
●
型別名と直和型の違い
– 型パラメーターとなり得るか
from typing import Generic, TypeVar, Union
AnyStr = TypeVar('AnyStr', str, bytes)
class AnyStrNode(Generic[AnyStr]):
...
UnionStr = Union[str, bytes]
class UnionStrNode(Generic[UnionStr]):
...
mypy
error: Free type variable expected in Generic[...]
型ヒント : ユーザー定義ジェネリック型
●
Generic という抽象基底クラスを継承する
from typing import Generic, TypeVar
T = TypeVar('T')
class Stack(Generic[T]):
def __init__(self) -> None:
self.items = [] # type: List[T]
def push(self, item: T) -> None:
self.items.append(item)
def pop(self) -> T:
return self.items.pop()
s = Stack() # type: Stack[int]
s.push(3)
s.push(5)
s.pop()
s.push('x')
s = Stack[int]()
...
mypy
mypy
generics_stack.py:19: error:
Argument 1 to "push" of "Stack" has incompatible type "str";
expected "int"
error: Generic type not valid as an expression
any more (use '# type:' comment instead)
型ヒント : 型消去
●
ユーザー定義のジェネリック型はインスタンス
化できる
from typing import TypeVar, Generic
T = TypeVar('T')
class Node(Generic[T]):
...
x = Node[T]() # The type inferred for x is Node[T].
print('x.__class__:', x.__class__)
y = Node[int]() # The type inferred for y is Node[int].
print('y.__class__:', y.__class__)
z = Node() # Inferred type is Node[Any].
print('z.__class__:', z.__class__)
実行時に型情報は
保持していない
$ python generics_type_erasure.py
x.__class__: __main__.Node[~T]
y.__class__: __main__.Node[~T]
z.__class__: __main__.Node[~T]
型ヒント : 数値型階層 (numeric tower)
●
numbers モジュールに抽象基底クラスを定義
complex 型 int/float 型を許容する
def add_int(num: int) -> int:
return num + 1
print(add_int(1))
print(add_int(2.4))
print(add_int(complex('3+4J')))
# floatは割愛
def add_complex(num: complex) -> complex:
return num + complex('1+2J')
print(add_complex(7))
print(add_complex(8.14))
print(add_complex(complex('9+10J')))
mypy
error: Argument 1 to "add_int" has
incompatible type "float"; expected "int"
error: Argument 1 to "add_int" has
incompatible type "complex"; expected "int"
型ヒント : スタブファイル
●
型チェッカーのための拡張モジュール
●
型ヒントを Python モジュールではなく外部の
ファイルに書き出すためのもの
●
拡張子は .pyi
●
主には ( 型ヒントがない ) サードパーティのラ
イブラリと一緒に型ヒントを使うため
– スタブを集める typeshedリポジトリもある
●
TypeScript でいうところの DefinitelyTyped
型ヒント : スタブの例
class tzinfo:
def tzname(self, dt: Optional[datetime]) -> str: ...
def utcoffset(self, dt: Optional[datetime]) -> int: ...
def dst(self, dt: Optional[datetime]) -> int: ...
def fromutc(self, dt: datetime) -> datetime: ..
class timezone(tzinfo):
utc = ... # type: tzinfo
min = ... # type: tzinfo
max = ... # type: tzinfo
def __init__(self, offset: timedelta, name: str = '') -> None: ...
def __hash__(self) -> int: ...
datetime.pyi
型ヒント : その他
●
呼び出し可能オブジェクト
●
抽象ジェネリック型
●
上界をもつ型変数
●
共変性と反変性
●
前方参照
●
キャスト
●
...
PEP 484 を読んでください ...
懸念
懸念 :(Python に ) 必要か?
●
Python に型ヒントは本当に必要なのか?
●
Revenge of the Types: 型の復讐 (翻訳)
– Armin Ronacher 氏の問題提起
– 欲しいのは強力な型システムそのもの ≠型ヒント
●
代数的データ型 (Algebraic data type) の議論
– Python は言語の意味論が壊れてる?
●
Python 側実装と C 言語側実装による意味論の違い
●
CPython インタープリターの最適化のため
懸念 :Typed Clojure の現状
●
Why we’re no longer using Core.typed
●
CircleCI が本番環境で 2 年間使っていたが、止
めてしまった話
– 型チェックが遅くてインタラクティブに開発でき
ない
– core.typed が Clojure 言語全てをカバーしてない
– サードパーティライブラリの型アノテーションの
メンテが大変
展望
展望 : 構造的部分型 (Structual Subtyping)
●
構造的部分型の型チェックの前提案
– プロトコルという概念を導入
●
Sized, Iterable, Iterator など
– クラスの継承関係ではなく、メソッド実装の有無
で型チェックを行う (Go 言語のポリモルフィズム )
– うまくいけば 3.6 の PEP に出てくるかも?
●
クラスの継承関係で部分型を定義するのを公称
的部分型 (Nominal Subtyping) と言う
展望 : 構造的部分型への期待?
●
[Python-ideas] Structural type checking for
PEP 484
– Cory Benfield (hyper の作者 ) からの返信
– 自分は型ヒントに特に関心のない開発者の 1 人
だったんだけど、これは型チェックに関して懸念
していたことに対応できるものだと思う
まとめ
型ヒントの所感
●
型ヒントが成功を収めるかどうかは懐疑的
– 型ヒントが Python3 のキラーアプリというのは
まだ楽観的過ぎると私は思う→プロパガンダ
●
みんな強力な型システムを求めている
– NullPointerException の発生しない世界
●
型システムとプログラミングの関係を学ぶ
– プログラミングの幅が広がり楽しくなる!
Happy Coding
With Type Hints
1 of 39

Recommended

Pythonと型チェッカー by
Pythonと型チェッカーPythonと型チェッカー
Pythonと型チェッカーTetsuya Morimoto
12.4K views72 slides
世界一わかりやすいClean Architecture by
世界一わかりやすいClean Architecture世界一わかりやすいClean Architecture
世界一わかりやすいClean ArchitectureAtsushi Nakamura
47.1K views77 slides
分散学習のあれこれ~データパラレルからモデルパラレルまで~ by
分散学習のあれこれ~データパラレルからモデルパラレルまで~分散学習のあれこれ~データパラレルからモデルパラレルまで~
分散学習のあれこれ~データパラレルからモデルパラレルまで~Hideki Tsunashima
4.3K views48 slides
DockerコンテナでGitを使う by
DockerコンテナでGitを使うDockerコンテナでGitを使う
DockerコンテナでGitを使うKazuhiro Suga
18.8K views8 slides
開発速度が速い #とは(LayerX社内資料) by
開発速度が速い #とは(LayerX社内資料)開発速度が速い #とは(LayerX社内資料)
開発速度が速い #とは(LayerX社内資料)mosa siru
61.5K views18 slides
画像をテキストで検索したい!(OpenAI CLIP) - VRC-LT #15 by
画像をテキストで検索したい!(OpenAI CLIP) - VRC-LT #15画像をテキストで検索したい!(OpenAI CLIP) - VRC-LT #15
画像をテキストで検索したい!(OpenAI CLIP) - VRC-LT #15Shuyo Nakatani
2.3K views25 slides

More Related Content

What's hot

協調フィルタリング入門 by
協調フィルタリング入門協調フィルタリング入門
協調フィルタリング入門hoxo_m
46.2K views35 slides
入門 Kubeflow ~Kubernetesで機械学習をはじめるために~ (NTT Tech Conference #4 講演資料) by
入門 Kubeflow ~Kubernetesで機械学習をはじめるために~ (NTT Tech Conference #4 講演資料)入門 Kubeflow ~Kubernetesで機械学習をはじめるために~ (NTT Tech Conference #4 講演資料)
入門 Kubeflow ~Kubernetesで機械学習をはじめるために~ (NTT Tech Conference #4 講演資料)NTT DATA Technology & Innovation
5.9K views56 slides
Kubernetesによる機械学習基盤への挑戦 by
Kubernetesによる機械学習基盤への挑戦Kubernetesによる機械学習基盤への挑戦
Kubernetesによる機械学習基盤への挑戦Preferred Networks
14.6K views18 slides
暗号技術の実装と数学 by
暗号技術の実装と数学暗号技術の実装と数学
暗号技術の実装と数学MITSUNARI Shigeo
9.6K views35 slides
デキるプログラマだけが知っているコードレビュー7つの秘訣 by
デキるプログラマだけが知っているコードレビュー7つの秘訣デキるプログラマだけが知っているコードレビュー7つの秘訣
デキるプログラマだけが知っているコードレビュー7つの秘訣Masahiro Nishimi
160K views41 slides
深層学習による自然言語処理入門: word2vecからBERT, GPT-3まで by
深層学習による自然言語処理入門: word2vecからBERT, GPT-3まで深層学習による自然言語処理入門: word2vecからBERT, GPT-3まで
深層学習による自然言語処理入門: word2vecからBERT, GPT-3までYahoo!デベロッパーネットワーク
25.7K views91 slides

What's hot(20)

協調フィルタリング入門 by hoxo_m
協調フィルタリング入門協調フィルタリング入門
協調フィルタリング入門
hoxo_m46.2K views
入門 Kubeflow ~Kubernetesで機械学習をはじめるために~ (NTT Tech Conference #4 講演資料) by NTT DATA Technology & Innovation
入門 Kubeflow ~Kubernetesで機械学習をはじめるために~ (NTT Tech Conference #4 講演資料)入門 Kubeflow ~Kubernetesで機械学習をはじめるために~ (NTT Tech Conference #4 講演資料)
入門 Kubeflow ~Kubernetesで機械学習をはじめるために~ (NTT Tech Conference #4 講演資料)
Kubernetesによる機械学習基盤への挑戦 by Preferred Networks
Kubernetesによる機械学習基盤への挑戦Kubernetesによる機械学習基盤への挑戦
Kubernetesによる機械学習基盤への挑戦
Preferred Networks14.6K views
デキるプログラマだけが知っているコードレビュー7つの秘訣 by Masahiro Nishimi
デキるプログラマだけが知っているコードレビュー7つの秘訣デキるプログラマだけが知っているコードレビュー7つの秘訣
デキるプログラマだけが知っているコードレビュー7つの秘訣
Masahiro Nishimi160K views
RLSを用いたマルチテナント実装 for Django by Takayuki Shimizukawa
RLSを用いたマルチテナント実装 for DjangoRLSを用いたマルチテナント実装 for Django
RLSを用いたマルチテナント実装 for Django
統計的係り受け解析入門 by Yuya Unno
統計的係り受け解析入門統計的係り受け解析入門
統計的係り受け解析入門
Yuya Unno23K views
Singularityで分散深層学習 by Hitoshi Sato
Singularityで分散深層学習Singularityで分散深層学習
Singularityで分散深層学習
Hitoshi Sato9.4K views
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」 by Takuto Wada
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
Takuto Wada148.6K views
サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23 by Masashi Shibata
サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23
サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23
Masashi Shibata11.2K views
GAN(と強化学習との関係) by Masahiro Suzuki
GAN(と強化学習との関係)GAN(と強化学習との関係)
GAN(と強化学習との関係)
Masahiro Suzuki83K views
Curriculum Learning (関東CV勉強会) by Yoshitaka Ushiku
Curriculum Learning (関東CV勉強会)Curriculum Learning (関東CV勉強会)
Curriculum Learning (関東CV勉強会)
Yoshitaka Ushiku63.9K views
マイクロにしすぎた結果がこれだよ! by mosa siru
マイクロにしすぎた結果がこれだよ!マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!
mosa siru132.6K views
【DL輪読会】DreamBooth: Fine Tuning Text-to-Image Diffusion Models for Subject-Dri... by Deep Learning JP
【DL輪読会】DreamBooth: Fine Tuning Text-to-Image Diffusion Models for Subject-Dri...【DL輪読会】DreamBooth: Fine Tuning Text-to-Image Diffusion Models for Subject-Dri...
【DL輪読会】DreamBooth: Fine Tuning Text-to-Image Diffusion Models for Subject-Dri...
Deep Learning JP1.4K views
DSIRNLP#1 ランキング学習ことはじめ by sleepy_yoshi
DSIRNLP#1 ランキング学習ことはじめDSIRNLP#1 ランキング学習ことはじめ
DSIRNLP#1 ランキング学習ことはじめ
sleepy_yoshi34.1K views
モデル高速化百選 by Yusuke Uchida
モデル高速化百選モデル高速化百選
モデル高速化百選
Yusuke Uchida24.7K views
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える by pospome
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考えるGoのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
pospome65.3K views
PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring) by Koichiro Matsuoka
PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)
PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)
Koichiro Matsuoka15.4K views
CRDT in 15 minutes by Shingo Omura
CRDT in 15 minutesCRDT in 15 minutes
CRDT in 15 minutes
Shingo Omura3.4K views

Similar to Python と型ヒント (Type Hints)

静的型付け言語Python by
静的型付け言語Python静的型付け言語Python
静的型付け言語Pythonkiki utagawa
4.6K views25 slides
mypy - 待望のPython3.9型ヒント対応 by
mypy - 待望のPython3.9型ヒント対応mypy - 待望のPython3.9型ヒント対応
mypy - 待望のPython3.9型ヒント対応KyutatsuNishiura
857 views20 slides
Pyconjp2014_implementations by
Pyconjp2014_implementationsPyconjp2014_implementations
Pyconjp2014_implementationsmasahitojp
4.7K views73 slides
C++ ポインタ ブートキャンプ by
C++ ポインタ ブートキャンプC++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプKohsuke Yuasa
11K views145 slides
PyPy 紹介 by
PyPy 紹介PyPy 紹介
PyPy 紹介shoma h
8.3K views82 slides
Python と型アノテーション by
Python と型アノテーションPython と型アノテーション
Python と型アノテーションK Yamaguchi
16.9K views27 slides

Similar to Python と型ヒント (Type Hints)(20)

静的型付け言語Python by kiki utagawa
静的型付け言語Python静的型付け言語Python
静的型付け言語Python
kiki utagawa4.6K views
mypy - 待望のPython3.9型ヒント対応 by KyutatsuNishiura
mypy - 待望のPython3.9型ヒント対応mypy - 待望のPython3.9型ヒント対応
mypy - 待望のPython3.9型ヒント対応
KyutatsuNishiura857 views
Pyconjp2014_implementations by masahitojp
Pyconjp2014_implementationsPyconjp2014_implementations
Pyconjp2014_implementations
masahitojp4.7K views
C++ ポインタ ブートキャンプ by Kohsuke Yuasa
C++ ポインタ ブートキャンプC++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプ
Kohsuke Yuasa11K views
PyPy 紹介 by shoma h
PyPy 紹介PyPy 紹介
PyPy 紹介
shoma h8.3K views
Python と型アノテーション by K Yamaguchi
Python と型アノテーションPython と型アノテーション
Python と型アノテーション
K Yamaguchi16.9K views
C++勉強会in広島プレゼン資料 by 真一 北原
C++勉強会in広島プレゼン資料C++勉強会in広島プレゼン資料
C++勉強会in広島プレゼン資料
真一 北原6.7K views
20170131 python3 6 PEP526 by masahitojp
20170131 python3 6 PEP526 20170131 python3 6 PEP526
20170131 python3 6 PEP526
masahitojp3.3K views
わんくま同盟大阪勉強会#61 by TATSUYA HAYAMIZU
わんくま同盟大阪勉強会#61わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61
TATSUYA HAYAMIZU957 views
Python 学習教材 (~299ページ) by Jun MITANI
Python 学習教材 (~299ページ)Python 学習教材 (~299ページ)
Python 学習教材 (~299ページ)
Jun MITANI249.1K views
明日からはじめるネットワーク運用自動化 by Taiji Tsuchiya
明日からはじめるネットワーク運用自動化明日からはじめるネットワーク運用自動化
明日からはじめるネットワーク運用自動化
Taiji Tsuchiya4.8K views
【DELPHI / C++BUILDER STARTER チュートリアルシリーズ】 シーズン2 Delphi の部 第2回 ‟変数と型„ by Kaz Aiso
【DELPHI / C++BUILDER STARTER チュートリアルシリーズ】 シーズン2 Delphi の部 第2回 ‟変数と型„【DELPHI / C++BUILDER STARTER チュートリアルシリーズ】 シーズン2 Delphi の部 第2回 ‟変数と型„
【DELPHI / C++BUILDER STARTER チュートリアルシリーズ】 シーズン2 Delphi の部 第2回 ‟変数と型„
Kaz Aiso525 views
Boost.Flyweight by gintenlabo
Boost.FlyweightBoost.Flyweight
Boost.Flyweight
gintenlabo2.7K views
TFLite_and_PyTorch_Mobile by yusuke shibui
TFLite_and_PyTorch_MobileTFLite_and_PyTorch_Mobile
TFLite_and_PyTorch_Mobile
yusuke shibui418 views
YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情 by Junichi Ishida
YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情
YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情
Junichi Ishida49.3K views
TypeScript で型を上手く使う試み.pdf by Ryo Higashigawa
TypeScript で型を上手く使う試み.pdfTypeScript で型を上手く使う試み.pdf
TypeScript で型を上手く使う試み.pdf
Ryo Higashigawa86 views
Python standard 2022 Spring by anyakichi
Python standard 2022 SpringPython standard 2022 Spring
Python standard 2022 Spring
anyakichi218 views

More from Tetsuya Morimoto

ビジネスパーソン x プログラミング by
ビジネスパーソン x プログラミングビジネスパーソン x プログラミング
ビジネスパーソン x プログラミングTetsuya Morimoto
499 views22 slides
チケット駆動開発のススメ by
チケット駆動開発のススメチケット駆動開発のススメ
チケット駆動開発のススメTetsuya Morimoto
525 views23 slides
PyLadies Tokyo 二周年記念パーティ LT by
PyLadies Tokyo 二周年記念パーティ LTPyLadies Tokyo 二周年記念パーティ LT
PyLadies Tokyo 二周年記念パーティ LTTetsuya Morimoto
1K views7 slides
PyCon JP 2016 ビギナーセッション by
PyCon JP 2016 ビギナーセッションPyCon JP 2016 ビギナーセッション
PyCon JP 2016 ビギナーセッションTetsuya Morimoto
1.4K views6 slides
Hyper Introduction by
Hyper IntroductionHyper Introduction
Hyper IntroductionTetsuya Morimoto
1.7K views20 slides
ストリーミングのげんざい by
ストリーミングのげんざいストリーミングのげんざい
ストリーミングのげんざいTetsuya Morimoto
87.7K views22 slides

More from Tetsuya Morimoto(16)

ビジネスパーソン x プログラミング by Tetsuya Morimoto
ビジネスパーソン x プログラミングビジネスパーソン x プログラミング
ビジネスパーソン x プログラミング
Tetsuya Morimoto499 views
チケット駆動開発のススメ by Tetsuya Morimoto
チケット駆動開発のススメチケット駆動開発のススメ
チケット駆動開発のススメ
Tetsuya Morimoto525 views
PyLadies Tokyo 二周年記念パーティ LT by Tetsuya Morimoto
PyLadies Tokyo 二周年記念パーティ LTPyLadies Tokyo 二周年記念パーティ LT
PyLadies Tokyo 二周年記念パーティ LT
Tetsuya Morimoto1K views
PyCon JP 2016 ビギナーセッション by Tetsuya Morimoto
PyCon JP 2016 ビギナーセッションPyCon JP 2016 ビギナーセッション
PyCon JP 2016 ビギナーセッション
Tetsuya Morimoto1.4K views
ストリーミングのげんざい by Tetsuya Morimoto
ストリーミングのげんざいストリーミングのげんざい
ストリーミングのげんざい
Tetsuya Morimoto87.7K views
Python3 プログラミング勉強会 by Tetsuya Morimoto
Python3 プログラミング勉強会Python3 プログラミング勉強会
Python3 プログラミング勉強会
Tetsuya Morimoto13.2K views
Ikazuchi introduction for Europython 2011 LT by Tetsuya Morimoto
Ikazuchi introduction for Europython 2011 LTIkazuchi introduction for Europython 2011 LT
Ikazuchi introduction for Europython 2011 LT
Tetsuya Morimoto687 views
Python界隈の翻訳プロジェクト by Tetsuya Morimoto
Python界隈の翻訳プロジェクトPython界隈の翻訳プロジェクト
Python界隈の翻訳プロジェクト
Tetsuya Morimoto3.5K views

Recently uploaded

速習! PostgreSQL専用HAソフトウェア: Patroni(PostgreSQL Conference Japan 2023 発表資料) by
速習! PostgreSQL専用HAソフトウェア: Patroni(PostgreSQL Conference Japan 2023 発表資料)速習! PostgreSQL専用HAソフトウェア: Patroni(PostgreSQL Conference Japan 2023 発表資料)
速習! PostgreSQL専用HAソフトウェア: Patroni(PostgreSQL Conference Japan 2023 発表資料)NTT DATA Technology & Innovation
18 views38 slides
Keycloakの全体像: 基本概念、ユースケース、そして最新の開発動向 by
Keycloakの全体像: 基本概念、ユースケース、そして最新の開発動向Keycloakの全体像: 基本概念、ユースケース、そして最新の開発動向
Keycloakの全体像: 基本概念、ユースケース、そして最新の開発動向Hitachi, Ltd. OSS Solution Center.
60 views26 slides
SSH応用編_20231129.pdf by
SSH応用編_20231129.pdfSSH応用編_20231129.pdf
SSH応用編_20231129.pdficebreaker4
335 views13 slides
The Things Stack説明資料 by The Things Industries by
The Things Stack説明資料 by The Things IndustriesThe Things Stack説明資料 by The Things Industries
The Things Stack説明資料 by The Things IndustriesCRI Japan, Inc.
58 views29 slides
定例会スライド_キャチs 公開用.pdf by
定例会スライド_キャチs 公開用.pdf定例会スライド_キャチs 公開用.pdf
定例会スライド_キャチs 公開用.pdfKeio Robotics Association
111 views64 slides
さくらのひやおろし2023 by
さくらのひやおろし2023さくらのひやおろし2023
さくらのひやおろし2023法林浩之
96 views58 slides

Recently uploaded(11)

速習! PostgreSQL専用HAソフトウェア: Patroni(PostgreSQL Conference Japan 2023 発表資料) by NTT DATA Technology & Innovation
速習! PostgreSQL専用HAソフトウェア: Patroni(PostgreSQL Conference Japan 2023 発表資料)速習! PostgreSQL専用HAソフトウェア: Patroni(PostgreSQL Conference Japan 2023 発表資料)
速習! PostgreSQL専用HAソフトウェア: Patroni(PostgreSQL Conference Japan 2023 発表資料)
SSH応用編_20231129.pdf by icebreaker4
SSH応用編_20231129.pdfSSH応用編_20231129.pdf
SSH応用編_20231129.pdf
icebreaker4335 views
The Things Stack説明資料 by The Things Industries by CRI Japan, Inc.
The Things Stack説明資料 by The Things IndustriesThe Things Stack説明資料 by The Things Industries
The Things Stack説明資料 by The Things Industries
CRI Japan, Inc.58 views
さくらのひやおろし2023 by 法林浩之
さくらのひやおろし2023さくらのひやおろし2023
さくらのひやおろし2023
法林浩之96 views
Windows 11 information that can be used at the development site by Atomu Hidaka
Windows 11 information that can be used at the development siteWindows 11 information that can be used at the development site
Windows 11 information that can be used at the development site
Atomu Hidaka88 views
SNMPセキュリティ超入門 by mkoda
SNMPセキュリティ超入門SNMPセキュリティ超入門
SNMPセキュリティ超入門
mkoda355 views
今、改めて考えるPostgreSQLプラットフォーム - マルチクラウドとポータビリティ -(PostgreSQL Conference Japan 20... by NTT DATA Technology & Innovation
今、改めて考えるPostgreSQLプラットフォーム - マルチクラウドとポータビリティ -(PostgreSQL Conference Japan 20...今、改めて考えるPostgreSQLプラットフォーム - マルチクラウドとポータビリティ -(PostgreSQL Conference Japan 20...
今、改めて考えるPostgreSQLプラットフォーム - マルチクラウドとポータビリティ -(PostgreSQL Conference Japan 20...

Python と型ヒント (Type Hints)

  • 2. 自己紹介 ● 森本 哲也 – twitter: @t2y ● 白ヤギコーポレーション所属 – カメリオAPI開発 ( 興味がある方はブースへ ) ● エキスパート Python プログラミング共訳 ● プログラミング言語歴 – Python (3 年 ) – → Java (3 年 ) – → Go ( 半年 )
  • 4. Pythonのパラドックス ● 2004 年 8 月 Paul Graham – Python を学ぼうとするプログラマーは賢い ● Python 2.3.4 (2004-05-27): 2.3 の時代 – 新しい言語を学ぶ人たちはプログラミングが好き であり、仕事に役立つから学ぶわけではない – 曲解 : 「優秀な Java プログラマーを採用したかっ たら Python プログラマーを雇えば良い」 ● いまは成り立たない
  • 5. Python3 のパラドックス ● 2015 年 10 月 – Python3 を現場に導入しようとするプログラマーは 賢い – Python3 を導入する人たちはプログラミングが好き であり、現場で役立つから導入するわけではない – 曲解 : 「優秀な Python プログラマーを採用した かったら Python3 を現場に導入すれば良い」 ● それっぽい? ( 自己責任で! )
  • 6. 概要 ● 背景 – 漸進的型付け→関数アノテーション→ mypy ● PEP 484 〜型ヒント〜 – 目的 – 型ヒントのために定義された型 (Any, Union, etc) – ジェネリクス ● 懸念 – 型ヒントの批判、 Typed Clojure の現在 ● 展望 – 構造的部分型 (Structual Subtyping) へ Python3.5
  • 8. 背景 : 漸進的型付け (Gradual Typing) ● Jeremy Siek 氏と Walid Taha 氏が 2006 年に 考案した型システム – 静的型付けと動的型付けを組み合わせられる – 双方の型システムの良いとこ取りしたもの – Object 型ではなく Any 型を導入しなければならな い背景の説明 ● PEP 484 の理論的背景 ● 入門記事 : 漸進的型付けとは何か
  • 9. 背景 : 関数アノテーション (PEP3017) ● Python3.0 で導入 (PEP3017) – 2008-12-03 リリース – 関数に任意のアノテーションを書く仕組み ● PEP 484 を支える基本的な仕組み – 関数アノテーションの用途を型アノテーションに 限定した – 関数オブジェクトの __annotations__ 属性に保持 されるのは同じ
  • 10. 背景 :mypy プロジェクト (1) ● http://mypy-lang.org/ ● 作者 : Jukka Lehtosalo 氏 – プログラマーを 6 年、マネージャーを 2 年 – 2009 年からケンブリッジ大学の博士課程 ● 2012 PyCon Finland – MYPY: A PYTHON VARIANT WITH SEAMLESS DYNA MIC AND STATIC TYPING ● 静的型付けと動的型付けの融合 – PyPy や Cython がライバル、 GIL のない VM
  • 11. 背景 :mypy プロジェクト (2) ● 現時点の mypy ができること – GIL のない VM – 型アノテーション→ PEP 484 で標準化 – 静的型チェッカーとしての Lint ツール ● PEP 484 では型チェッカーは提供しない
  • 13. 型ヒント : サンプルコード # -*- coding: utf-8 -*- import json import sys from pprint import pformat from typing import Any, Dict def pretty_format(data: Dict[str, Any]) -> str: return pformat(data, width=1) def main() -> None: raw_data = sys.argv[1] # type: str data = pretty_format(json.loads(raw_data)) print(data) data.append('mypy') main() $ mypy tutorial.py tutorial.py: note: In function "main": tutorial.py:14: error: "str" has no attribute "append"
  • 14. 型ヒント : 目的 ● 型アノテーションの構文を標準化 ● 静的解析 – Lint ツール ( オフライン型チェッカー ) ● IDE – コード補完やリファクタリング機能に利用 – Type Hinting in PyCharm ● ドキュメンテーション – 型アノテーションがそのまま使える? Python は 動的型付け言語
  • 16. 型ヒント :Any 型 ● 全ての型は Any 型のサブタイプ – object 型と似ているが、型チェッカーによる扱い が異なる ● object 型 – 型チェッカーは値のほとんどの操作を拒否する ● Any 型 – 型チェッカーは値の全ての操作を許容する
  • 17. any_and_object.py: note: In function "object_func": any_and_object.py:8: error: Unsupported left operand type for + ("object") 型ヒント :Any 型と object 型 from typing import Any def any_func(x: Any, y: Any) -> Any: return x + y def object_func(x: object, y: object) -> object: return x + y mypy object 型の操作は型チェカーでエラーとなる 理論的背景は「漸進的型付けとは何か」を参照
  • 18. 型ヒント : 直和型 (Union Type) ● 直和型 – 関数型プログラミング言語でよく使われるデータ型 – 典型的にはツリーのデータ構造を簡潔に表現できる ● 単一の引数に対して少数の期待される型の集合 をとる e = Union[Employee, Sequence[Employee]] # OCaml バリアント型 type day = Sun | Mon | Tue | Wed | Thu | Fri | Sat # 第7回「代数データ型」でいろいろなデータを表してみる
  • 19. 型ヒント :Optional 型 ● 直和型の応用 ● Union[T1, None] と Optional[T1] は等価 – None を取り得ることが明示される – None は多くの操作が型エラー ● Java の NullPointerException はこりごり – @Nonnull, @Nullable のアノテーションを明示 – Collections.emptyList(), Collections.emptyMap() ● Null 安全を型システムで保証する世界へ
  • 20. 型ヒント :Optional 型の例 from typing import Optional, Union def func1(data: Optional[int]) -> int: return 3 + data def func2(data: Union[int, None]) -> int: return 3 + data def func3(data: int=None) -> int: return 3 + data これらは等価な型ヒント ・デフォルト引数に None を指定したときも Optional 型として扱う TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
  • 21. 型ヒント : ジェネリクス ● コンテナー内の要素に期待する型を示す ● TypeVar というファクトリーを使って型変数を 定義する from typing import Sequence, TypeVar T = TypeVar('T') # Declare type variable def first(l: Sequence[T]) -> T: # Generic function return l[0]
  • 22. 型ヒント :TypeVar ● TypeVar のコンストラクタに渡す型変数を表す 文字列と代入する変数名は同じでなければいけ ない from typing import TypeVar X = TypeVar('X') # correct Z = TypeVar('Y') # error mypy generics_typevar.py:4: error: Unexpected TypeVar() argument value
  • 23. 型ヒント :TypeVar の例 ● typing モジュールにいくつか定義されてる # Some unconstrained type variables. These are used by the container types. T = TypeVar('T') # Any type. KT = TypeVar('KT') # Key type. VT = TypeVar('VT') # Value type. T_co = TypeVar('T_co', covariant=True) # Any type covariant containers. V_co = TypeVar('V_co', covariant=True) # Any type covariant containers. VT_co = TypeVar('VT_co', covariant=True) # Value type covariant containers. T_contra = TypeVar('T_contra', contravariant=True) # Ditto contravariant. # A useful type variable with constraints. This represents string types. # TODO: What about bytearray, memoryview? AnyStr = TypeVar('AnyStr', bytes, str) 型の別名
  • 24. 型ヒント : 型別名と直和型 ● 型別名と直和型の違い – 型パラメーターとなり得るか from typing import Generic, TypeVar, Union AnyStr = TypeVar('AnyStr', str, bytes) class AnyStrNode(Generic[AnyStr]): ... UnionStr = Union[str, bytes] class UnionStrNode(Generic[UnionStr]): ... mypy error: Free type variable expected in Generic[...]
  • 25. 型ヒント : ユーザー定義ジェネリック型 ● Generic という抽象基底クラスを継承する from typing import Generic, TypeVar T = TypeVar('T') class Stack(Generic[T]): def __init__(self) -> None: self.items = [] # type: List[T] def push(self, item: T) -> None: self.items.append(item) def pop(self) -> T: return self.items.pop() s = Stack() # type: Stack[int] s.push(3) s.push(5) s.pop() s.push('x') s = Stack[int]() ... mypy mypy generics_stack.py:19: error: Argument 1 to "push" of "Stack" has incompatible type "str"; expected "int" error: Generic type not valid as an expression any more (use '# type:' comment instead)
  • 26. 型ヒント : 型消去 ● ユーザー定義のジェネリック型はインスタンス 化できる from typing import TypeVar, Generic T = TypeVar('T') class Node(Generic[T]): ... x = Node[T]() # The type inferred for x is Node[T]. print('x.__class__:', x.__class__) y = Node[int]() # The type inferred for y is Node[int]. print('y.__class__:', y.__class__) z = Node() # Inferred type is Node[Any]. print('z.__class__:', z.__class__) 実行時に型情報は 保持していない $ python generics_type_erasure.py x.__class__: __main__.Node[~T] y.__class__: __main__.Node[~T] z.__class__: __main__.Node[~T]
  • 27. 型ヒント : 数値型階層 (numeric tower) ● numbers モジュールに抽象基底クラスを定義 complex 型 int/float 型を許容する def add_int(num: int) -> int: return num + 1 print(add_int(1)) print(add_int(2.4)) print(add_int(complex('3+4J'))) # floatは割愛 def add_complex(num: complex) -> complex: return num + complex('1+2J') print(add_complex(7)) print(add_complex(8.14)) print(add_complex(complex('9+10J'))) mypy error: Argument 1 to "add_int" has incompatible type "float"; expected "int" error: Argument 1 to "add_int" has incompatible type "complex"; expected "int"
  • 28. 型ヒント : スタブファイル ● 型チェッカーのための拡張モジュール ● 型ヒントを Python モジュールではなく外部の ファイルに書き出すためのもの ● 拡張子は .pyi ● 主には ( 型ヒントがない ) サードパーティのラ イブラリと一緒に型ヒントを使うため – スタブを集める typeshedリポジトリもある ● TypeScript でいうところの DefinitelyTyped
  • 29. 型ヒント : スタブの例 class tzinfo: def tzname(self, dt: Optional[datetime]) -> str: ... def utcoffset(self, dt: Optional[datetime]) -> int: ... def dst(self, dt: Optional[datetime]) -> int: ... def fromutc(self, dt: datetime) -> datetime: .. class timezone(tzinfo): utc = ... # type: tzinfo min = ... # type: tzinfo max = ... # type: tzinfo def __init__(self, offset: timedelta, name: str = '') -> None: ... def __hash__(self) -> int: ... datetime.pyi
  • 32. 懸念 :(Python に ) 必要か? ● Python に型ヒントは本当に必要なのか? ● Revenge of the Types: 型の復讐 (翻訳) – Armin Ronacher 氏の問題提起 – 欲しいのは強力な型システムそのもの ≠型ヒント ● 代数的データ型 (Algebraic data type) の議論 – Python は言語の意味論が壊れてる? ● Python 側実装と C 言語側実装による意味論の違い ● CPython インタープリターの最適化のため
  • 33. 懸念 :Typed Clojure の現状 ● Why we’re no longer using Core.typed ● CircleCI が本番環境で 2 年間使っていたが、止 めてしまった話 – 型チェックが遅くてインタラクティブに開発でき ない – core.typed が Clojure 言語全てをカバーしてない – サードパーティライブラリの型アノテーションの メンテが大変
  • 35. 展望 : 構造的部分型 (Structual Subtyping) ● 構造的部分型の型チェックの前提案 – プロトコルという概念を導入 ● Sized, Iterable, Iterator など – クラスの継承関係ではなく、メソッド実装の有無 で型チェックを行う (Go 言語のポリモルフィズム ) – うまくいけば 3.6 の PEP に出てくるかも? ● クラスの継承関係で部分型を定義するのを公称 的部分型 (Nominal Subtyping) と言う
  • 36. 展望 : 構造的部分型への期待? ● [Python-ideas] Structural type checking for PEP 484 – Cory Benfield (hyper の作者 ) からの返信 – 自分は型ヒントに特に関心のない開発者の 1 人 だったんだけど、これは型チェックに関して懸念 していたことに対応できるものだと思う
  • 38. 型ヒントの所感 ● 型ヒントが成功を収めるかどうかは懐疑的 – 型ヒントが Python3 のキラーアプリというのは まだ楽観的過ぎると私は思う→プロパガンダ ● みんな強力な型システムを求めている – NullPointerException の発生しない世界 ● 型システムとプログラミングの関係を学ぶ – プログラミングの幅が広がり楽しくなる!