''' 本例的基本模式还是观察者 基类 Subject 提供注册和提醒注册上的对象提醒机制 因为函数和参数混杂在一起传递,使得各个模块的处理结构其实是 case by case ''' from collections import Counter from typing import List from cppy.cp_util import * class Subject: def register_handler(self, handler: callable, *args, **kwargs): self.handler = handler self.args = args self.kwargs = kwargs def notify(self, *args, **kwargs): self.handler( self.data, *self.args, **self.kwargs) # 组件一:TextLoader - 负责读取文本并过滤停用词 class TextLoader(Subject): def load_text(self, filename: str) -> List[str]: return extract_file_words(filename) def notify(self, *args, **kwargs): filename = args[0] self.data = self.load_text(filename) super().notify(self.data, *args, **kwargs) # 组件二:WordCounter - 计算词频 class WordCounter(Subject): def count_words(self, words: List[str]) -> dict: return Counter(words) def notify(self, *args, **kwargs ): words = args[0] self.data = self.count_words(words) super().notify(self.data, *args, **kwargs) # 组件三:TopWordsPresenter - 排序并输出前10个词 class TopWordsPresenter(Subject): def notify(self, words,*args, **kwargs): n = args[0] top_words = words.most_common(n) print_word_freqs( top_words ) # 主程序逻辑 def main(): loader = TextLoader() counter = WordCounter() presenter = TopWordsPresenter() # 注册事件处理器 loader.register_handler(counter.notify) counter.register_handler( presenter.notify,10 ) # 触发加载文本并开始流程 loader.notify(testfilepath) if __name__ == "__main__": main()