2017-05-24 8 views
5

xの長さxreadread() - > str。ダックタイピング3.5スタイルの型注釈

だから私は引数として任意のpythonファイルオブジェクトを使用することができます(これはreadlineメソッドを持っているので)、私は何も実装していないオブジェクトを提供することもできますしかし、それは完全に受け入れられるでしょう。

この関数定義を書き直して、第2引数に注釈を付けることができますか?

答えて

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" 
+0

このような深い回答をいただきありがとうございます。 –

+0

実行時に 'isinstance'がパスをチェックするように[' __subclasshook__'](https://docs.python.org/3/library/abc.html#abc.ABCMeta.__subclasshook__)を実装することができます。 – user2357112

3

PEP544 https://www.python.org/dev/peps/pep-0544/によって構造的サブタイプ(スタティックダックタイピング)が提案されている。受け入れられた場合、明示的なサブクラス化は必要ありません。静的型チェッカーで理解できる独自のプロトコルを簡単に定義することができます。