疑問
次のコードがmypyの型チェックでエラーになりました。
get
メソッドはMyData
型を返すとしていますが、None
を返しているためです。
class MyClass(ABC):
@abstractmethod
def get(self) -> MyData:
return None # 型ヒントと不一致
抽象メソッドには実装が存在しないことを示すべきですが、returnを書いてしまうと型チェックに引っかかります。
正しい記述方法を検討してみました。
解決方法
抽象メソッドの本体には何も実装しないことが重要です。次の記述が一般的です。
Ellipsis リテラル
class MyClass(ABC):
@abstractmethod
def get(self) -> MyData:
...
…
は、は未実装を示す視覚的なシンプルな記述です。Ellipsis リテラルとしてPythonに組み込まれています。
pass文
class MyClass(ABC):
@abstractmethod
def get(self) -> MyData:
pass
pass
はPythonの伝統的な記述です。公式ドキュメントでもpassがよく用いられています。
dockstringを書く
class MyClass(ABC):
@abstractmethod
def get(self) -> MyData:
"""Dataを取得するを取得する."""
docstringがある場合、mypyエラーは発生しませんが、...を併用して未実装を明示してもよいとおもいます。
docstringとpass
を併用すると、ruff check
でPIE790('Unnecessary `pass` statement')
警告となります。
どの記述がよいか?
どの記述にするかはプロジェクトのコーディングルール次第ですが、...
を使う方が最近のトレンドとして増えている気がします。未実装の関数を一目で確認でき、ruffのチェックにも適合しやすいです。
まとめ
- 抽象メソッドにreturnを書くと型チェックエラーになる
-
...
(Ellipsis)を使うと視覚的に未実装を示せる - passは従来の方法だが、冗長になる場合もある(ruffで警告)
- docstringを書くだけでもエラーは避けられるが、
...
を追加するのも可(開発のコーディングルール次第)
class MyClass(ABC):
@abstractmethod
def get(self) -> MyData:
"""Dataを取得するを取得する."""
...
参考
https://tuxtimo.me/posts/2021/11/05/python-pass-vs.-ellipsis/
https://qiita.com/kissy24/items/d9564d1f48a310614e90