我应该如何注释可以返回多种不同类型对象的方法的返回类型?
具体来说,这是我遇到问题的方法:
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方法。这些错误似乎围绕着这样一个事实,即联盟中的所有三种对象类型都有不同的属性。
答案 0 :(得分:1)
Here's a solution using 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())
Alternately, if you're willing to modify your approach a bit more, you can provide a cleaner API:
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())