xの長さxreadread() - > str。ダックタイピング3.5スタイルの型注釈
だから私は引数として任意のpythonファイルオブジェクトを使用することができます(これはreadlineメソッドを持っているので)、私は何も実装していないオブジェクトを提供することもできますしかし、それは完全に受け入れられるでしょう。
この関数定義を書き直して、第2引数に注釈を付けることができますか?
xの長さxreadread() - > str。ダックタイピング3.5スタイルの型注釈
だから私は引数として任意のpythonファイルオブジェクトを使用することができます(これはreadlineメソッドを持っているので)、私は何も実装していないオブジェクトを提供することもできますしかし、それは完全に受け入れられるでしょう。
この関数定義を書き直して、第2引数に注釈を付けることができますか?
このソリューションは、あなたが探している正確に何と同等ではありません。
あなたは代わりに、私たちはそのカスタム抽象基本クラスを定義している限り、
x.readline() -> str
として
xを任意のオブジェクトを持つことができます子クラスによって定義される抽象メソッドがreadline
であると想定しています。したがって、任意のオブジェクトの代わりに、この新しい抽象基本クラスのインスタンスのみを受け入れ、より明示的にします。
from abc import ABC, abstractmethod
class FileObject(ABC):
@abstractmethod
def readline(self):
raise NotImplementedError()
今、私たちはFileObject
のPythonのファイルオブジェクトとインスタンスを操作することができ、カスタム型を定義しようとしている。
from typing import IO, TypeVar
StreamType = TypeVar('StreamType', IO, FileObject)
def func(name: str, stream: StreamType) -> None:
pass
今度はmypyを使用してテストしてみましょう:
from io import StringIO, BytesIO
class X(FileObject):
def readline(self):
pass
func('a', StringIO()) # passed
func('a', BytesIO()) # passed
func('a', open('foo.txt')) # passed
func('a', X()) # passed
func('a', object()) # failed
func('a', []) # failed
func('a', 1) # failed
出力:
$ mypy so.py
so.py:33: error: Type argument 1 of "func" has incompatible value "object"
so.py:34: error: Type argument 1 of "func" has incompatible value List[None]
so.py:35: error: Type argument 1 of "func" has incompatible value "int"
PEP544 https://www.python.org/dev/peps/pep-0544/によって構造的サブタイプ(スタティックダックタイピング)が提案されている。受け入れられた場合、明示的なサブクラス化は必要ありません。静的型チェッカーで理解できる独自のプロトコルを簡単に定義することができます。
このような深い回答をいただきありがとうございます。 –
実行時に 'isinstance'がパスをチェックするように[' __subclasshook__'](https://docs.python.org/3/library/abc.html#abc.ABCMeta.__subclasshook__)を実装することができます。 – user2357112