Pythonは動的型付け言語なので、基本的に型を意識する必要がない。
が、VS CodeなどのIDEでインテリセンスがあまり効かないため、
どんなデータ型が渡されているかを推測しながら書く必要がある。
これは、静的型付け言語に慣れた身にはつらい。
typingを利用
3.5から、typingモジュールが標準でセットされ、
型ヒントがサポートされた。
実行時エラーは発生しないものの、
VS Codeでコーディング時に次の挙動をしてくれる。
- 型に応じたインテリセンスを提示
- 定義した型が渡されなかった場合にエラー表示
基本的な使い方
関数定義時に利用したり、変数定義時に利用する
- 関数定義:
- 返値のある場合:def func(args:型) -> 型 :
- 返値のない場合:def funca(args:型) -> NoReturn:
※from typing import NoReturnをしておく
型は、strやintなど色々指定できる
型ヒントに自作クラスを指定する
どうやるんだろ?と思い、typingモジュールのドキュメントを探索。
typing.Type()という関数があったので、これを試してみることにする。
入門Python3の例題をちょっと改変
class_test.pyというクラスを作り、挙動を確認する
import typing as tp
class Tail():
def __init__(self, tail:str):
self.__tail = tail
@property
def tail(self) -> str:
return(self.__tail)
@tail.setter
def tail(self,tail:str):
self.__tail = tail
class pBill():
"""型指定なし
"""
def __init__(self, description):
self.__description = description
@property
def description(self):
return(self.__description)
@description.setter
def description(self,description):
self.__description = description
class Bill():
"""型指定あり
"""
def __init__(self, description:str):
self.__description = description
@property
def description(self) -> str:
return(self.__description)
@description.setter
def description(self,description:str):
self.__description = description
class pDack():
"""型指定なし
"""
def __init__(self, bill, tail):
self.bill = bill
self.tail = tail
def about(self):
print("This duck has a ",self.bill.description," and tail=",self.tail.tail)
class Dack():
"""型指定あり
"""
def __init__(self, bill:tp.Type[Bill], tail:tp.Type[Tail]):
self.bill = bill
self.tail = tail
def about(self):
print("This duck has a ",self.bill.description," and tail=",self.tail.tail)
cbill = Bill('くちばし')
ctail = Tail('しっぽ')
cdack = Dack(cbill,ctail)
cdack.about()
### 以下のコードは実行時エラーなし のはず
bill = Bill([])
tail = Tail({})
dack = Dack(bill,tail)
dack2 = Dack(1,2)
dack.about()
まずは挙動の確認から。
class_test.pyを実行してみる。
予想通り、エラーは起きない
$ python class_test.py
This duck has a くちばし and tail= しっぽ
This duck has a [] and tail= {}
続いて、インテリセンスの挙動を確認。
型指定なしの場合
self.bill にはどんな型が来るのか明示していないので、
self.bill. と打っても何もでない。
型指定ありの場合
self.bill にBillクラスが渡されることを明示しているので、
self.bill.と打つとインテリセンスが表示される。
また、descriptionはstr型とわかる。
補足
tp.Type[Bill]とか長ったらしくしなくても
通常の変数みたいに :クラス名 で大丈夫らしい。
こっちのほうがすっきりする。
class Dack():
"""型指定あり
"""
def __init__(self, bill:Bill, tail:Tail):
self.bill = bill
self.tail = tail
def about(self):
print("This duck has a ",self.bill.description," and tail=",self.tail.tail)