![](/img/trans.png)
[英]Python: How to specify function return type in a mixin method
[英]Specify return type of a wrapper function that calls an abstract method in Python
對於此示例,請考慮Solver
將返回Solution
的簡化場景。
我們有Solution
:
class Solution(ABC):
pass
class AnalyticalSolution(Solution):
pass
class NumericalSolution(Solution):
def get_mesh_size(self) -> float:
return 0.12345
和Solver
:
class Solver(ABC):
def solve(self, task: int) -> Solution:
# Do some pre-processing with task
# ...
return self._solve(task)
@abstractmethod
def _solve(self, task: int) -> Solution:
pass
class NumericalSolver(Solver):
def _solve(self, task: int) -> NumericalSolution:
return NumericalSolution()
class AnalyticalSolver(Solver):
def _solve(self, task: int) -> AnalyticalSolution:
return AnalyticalSolution()
我遇到的問題是由包裝方法solve
的實現引起的,然后調用抽象方法_solve
。 我經常遇到這樣的情況,我想在對所有求解器都相同的solve
方法中進行一些預處理,但是_solve
的實際實現可能會有所不同。
如果我現在調用數值求解器並調用get_mesh_size()
方法,Pylance(正確地)告訴我Solution
object 沒有get_mesh_size
成員。
if __name__ == "__main__":
solver = NumericalSolver()
solution = solver.solve(1)
print(solution.get_mesh_size())
我知道 Pylance 只看到solve
的接口,這表明返回類型是Solution
object 不需要有get_mesh_size
方法。 我也知道這個例子在運行時有效。
我嘗試像這樣使用TypeVar
(實際上,因為 ChatGPT 建議這樣做):
class Solution(ABC):
pass
T = TypeVar("T", bound=Solution)
然后重寫Solver
class:
class Solver(ABC):
def solve(self, task: int) -> T:
# Do some pre-processing with task
# ...
return self._solve(task)
@abstractmethod
def _solve(self, task: int) -> T:
pass
但是 Pylance 現在告訴我TypeVar "T" appears only once in generic function signature
。 所以這不是解決方案。
我如何輸入才能使用此示例?
您可以使用Generic[T]
作為Solver
的基礎,然后按如下方式擴展它
from abc import ABC, abstractmethod
from typing import TypeVar, Generic
class Solution(ABC):
pass
class AnalyticalSolution(Solution):
pass
class NumericalSolution(Solution):
def get_mesh_size(self) -> float:
return 0.12345
SolutionGeneric = TypeVar("SolutionGeneric", bound=Solution)
class Solver(ABC, Generic[SolutionGeneric]):
def solve(self, task: int) -> SolutionGeneric:
# Do some pre-processing with task
# ...
return self._solve(task)
@abstractmethod
def _solve(self, task: int) -> SolutionGeneric:
pass
class NumericalSolver(Solver[NumericalSolution]):
def _solve(self, task: int) -> NumericalSolution:
return NumericalSolution()
class AnalyticalSolver(Solver):
def _solve(self, task: int) -> AnalyticalSolution:
return AnalyticalSolution()
if __name__ == "__main__":
solver = NumericalSolver()
solution = solver.solve(1)
print(solution.get_mesh_size())
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.