今天,我遇到了根据子方法的实现来输入父方法的任务。我的意思是,我有一堂这样的课:
from abc import ABC, abstractmethod
class PageIterator(ABC):
def __init__(self, last_page):
self.current_page = 1
self.last_page = last_page
def __iter__(self):
return self
def __next__(self):
if self.current_page > self.last_page:
raise StopIteration
response = self.get()
self.current_page += 1
return response
@abstractmethod
def get(self):
...
我认为从上下文中可以清楚地看出,该类是通过网站页面的顺序通道的实现。在这种情况下,有一个抽象方法get
,其实现落在子类上。根据实现的不同,get
它可以返回不同的对象。例如,实现如下:
from dataclasses import dataclass
@dataclass()
class CurrentPage:
page: int
@dataclass()
class LastPage:
last_page: int
class MainPage(PageIterator):
def get(self):
return CurrentPage(self.current_page)
class CommentPage(PageIterator):
def get(self):
return LastPage(self.current_page)
用法大致如下:
for i in MainPage(100):
print(i)
for j in CommentPage(100):
print(j)
代码可以工作,但问题是IDE
(我尝试了PyCharm
和 的几个版本VSCode
)中的静态代码分析工具无法独立确定迭代器和显示返回值的类型Any
。合乎逻辑的做法是添加如下内容:
@abstractmethod
def get(self) -> Union[CurrentPage, LastPage]:
...
或这个:
def __next__(self) -> Union[CurrentPage, LastPage]:
会出现提示,但返回类型是IDE
混合的(如果对象很大并且具有许多内部字段,则至关重要)。我想为每个实现提供单独的提示。此时,我的技术已经不够了,我唯一能想到的就是将其__next__
也抽象化,并在每个子类中将其与类型提示一起编写,但这已经看起来像是重复的代码,这不太好。 。