2017-11-05 7 views
1

複数の異なるタイプのオブジェクトを返すことができるメソッドの戻り値の型には、どのように注釈を付ける必要がありますか?Python/MyPy:いくつかの異なるタイプのオブジェクトのいずれかを返すメソッドに注釈を付けるにはどうすればいいですか?

具体的に、これは私がとのトラブルを抱えている方法である:

def _bin_factory(self) -> Any: 
    """ 
    Returns a bin with the specificed algorithm, 
    heuristic, and dimensions 
    """ 
    if self.algorithm == 'guillotine': 
     return guillotine.Guillotine(self.bin_width, self.bin_height, self.rotation, 
            self.rectangle_merge, self.split_heuristic) 
    elif self.algorithm == 'shelf': 
     return shelf.Sheet(self.bin_width, self.bin_height, self.rotation, self.wastemap) 
    elif self.algorithm == 'maximal_rectangle': 
     return maximal_rectangles.MaximalRectangle(self.bin_width, self.bin_height, self.rotation) 
    raise ValueError('Error: No such Algorithm') 

私はUnion[shelf.Sheet, guillotine.Guillotine, maximal_rectangles.MaximalRectangle]を試みたが、MyPyは私に、私は私のコードの後半で_bin_factoryメソッドを使用して、エラーのトンを提供します。このエラーは、連合の3つのオブジェクトタイプがそれぞれ互いに異なる属性を持つという事実を中心にしているようです。

+0

ひとつのアイデアは、それぞれを変更することですそれらは 'bin()'メソッドを含む "Bin"クラスをサブクラス化します。次に、 '_bin_factory()'メソッドを変更して、 'Bin'型のオブジェクトを返します。こうすれば、ビニング戦略に関係なく、呼び出し側は 'bin()'メソッドを呼び出し、返された型をすべて同じ種類のものとして扱うことができます。 – Michael0x2a

答えて

0

ここではもう少しあなたのアプローチを変更するために喜んでいる場合、あなたはクリーンなAPIを提供することができ、代わりにtyping.Generic

from typing import Generic, TypeVar 

T = TypeVar('T', 'Guillotine', 'Sheet', 'MaximalRectangle') 

class Guillotine: 
    pass 

class Sheet: 
    pass 

class MaximalRectangle: 
    pass 

class Algo(Generic[T]): 
    def __init__(self, algorithm: str) -> None: 
     self.algorithm = algorithm 

    def _bin_factory(self) -> T: 
     """ 
     Returns a bin with the specificed algorithm, 
     heuristic, and dimensions 
     """ 
     if self.algorithm == 'guillotine': 
      return Guillotine() # type: ignore 
     elif self.algorithm == 'shelf': 
      return Sheet() # type: ignore 
     elif self.algorithm == 'maximal_rectangle': 
      return MaximalRectangle() # type: ignore 
     raise ValueError('Error: No such Algorithm') 


algo: Algo[Guillotine] = Algo('guillotine') 
reveal_type(algo._bin_factory()) 

を使用してソリューションです:

from typing import Generic, TypeVar, Type 

T = TypeVar('T', 'Guillotine', 'Sheet', 'MaximalRectangle') 

class Guillotine: 
    pass 

class Sheet: 
    pass 

class MaximalRectangle: 
    pass 

class Algo(Generic[T]): 
    def __init__(self, algorithm: Type[T]) -> None: 
     self.algorithm = algorithm # type: Type[T] 

    def _bin_factory(self) -> T: 
     """ 
     Returns a bin with the specificed algorithm, 
     heuristic, and dimensions 
     """ 
     if self.algorithm is Guillotine: 
      # handle custom arguments: 
      return self.algorithm() 
     elif self.algorithm is Sheet: 
      # handle custom arguments: 
      return self.algorithm() 
     elif self.algorithm is MaximalRectangle: 
      # handle custom arguments: 
      return self.algorithm() 
     raise ValueError('Error: No such Algorithm') 

algo = Algo(Guillotine) 
reveal_type(algo._bin_factory()) 
関連する問題