Python 简单项目的设计模式[工厂vs原型]? 我正在制作一个脚本,其中刮许多新闻网站和回报 文章 有一个名为Website的类,其属性为name, url,以及文章。每个Wehsite子类都有一个唯一的方法 对于获取文章 我的目标是收集所有的文章 并返回类型为{name:articles}的词典。所以 这是我到目前为止所拥有的

Python 简单项目的设计模式[工厂vs原型]? 我正在制作一个脚本,其中刮许多新闻网站和回报 文章 有一个名为Website的类,其属性为name, url,以及文章。每个Wehsite子类都有一个唯一的方法 对于获取文章 我的目标是收集所有的文章 并返回类型为{name:articles}的词典。所以 这是我到目前为止所拥有的,python,oop,design-patterns,software-design,Python,Oop,Design Patterns,Software Design,具体问题: 我认为这是一个工厂模式问题。这是解决这个问题的最好办法吗 对于self.name、self.url和self.articles在第一个网站课程中应该使用的内容,有什么最佳实践吗?我只是将它们全部设置为占位符值,因为它们都将被覆盖 这完全是一个意见问题。您的方法取决于Python枚举子类的能力。我可能更喜欢下面的解决方案,其中有一个抽象基类Website,它具有属性name和url以及一个方法get_articles,需要重写该方法。然后我将有一个类调用ArticleFetcher

具体问题:

  • 我认为这是一个工厂模式问题。这是解决这个问题的最好办法吗
  • 对于
    self.name
    self.url
    self.articles
    在第一个
    网站
    课程中应该使用的内容,有什么最佳实践吗?我只是将它们全部设置为占位符值,因为它们都将被覆盖

这完全是一个意见问题。您的方法取决于Python枚举子类的能力。我可能更喜欢下面的解决方案,其中有一个抽象基类
Website
,它具有属性
name
url
以及一个方法
get_articles
,需要重写该方法。然后我将有一个类调用
ArticleFetcher
Website
的实例向其注册。然后,当您在
artcleetcher
上调用方法
get_articles
(这是一个类方法生成器函数)时,它通过在所有已注册(委派)的
网站
实例上调用
get_articles
来实现这一点。注意:
WebSite
子类中的
get\u articles
方法也可以(应该?)实现为生成器函数

from abc import ABCMeta, abstractmethod


class ArticleFetcher:
    websites = []

    @classmethod
    def register_website(cls, website):
        cls.websites.append(website)

    @classmethod
    def get_articles(cls):
        for website in cls.websites:
            for article in website.get_articles():
                yield website.name, article

class Website(metaclass=ABCMeta):
    def __init__(self, name, url):
        self.name = name
        self.url = url
        ArticleFetcher.register_website(self)

    @abstractmethod
    def get_articles(self):
        raise NotImplemented()

class Website1(Website):
    """Implementation for Website1"""
    def __init__(self):
        super().__init__('Website1', 'www.google.com')

    def get_articles(self):
        # insert custom logic to get articles based on url
        return ['article 1', 'article 2', 'article 3']
        """
        # alternate implementation:
        yield 'article 1'
        yield 'article 2'
        yield 'article 3'
        """

class Website2(Website):
    """Implementation for Website2"""
    def __init__(self):
        super().__init__('Website2', 'www.microsoft.com')

    def get_articles(self):
        # insert custom logic to get articles based on url
        return ['article 3', 'article 4', 'article 5']

w1 = Website1()
w2 = Website2()
for name, article in ArticleFetcher.get_articles():
    print(name, article)
印刷品:

Website1 article 1
Website1 article 2
Website1 article 3
Website2 article 3
Website2 article 4
Website2 article 5
我觉得这更干净。您只需要实例化那些子类,即您希望检索其文章的网站。因此,您可能已经定义了
网站
的10个子类,但是如果您只想检索其中4个的文章,那么您只能实例化这4个实例。你的设计不允许这样。如果您总是希望检索已定义的所有网站类的文章,那么在类定义之后立即创建网站类的实例就很简单了。

Website1 article 1
Website1 article 2
Website1 article 3
Website2 article 3
Website2 article 4
Website2 article 5