以编程方式创建子类

2024-05-23 22:42:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用Scrapy来抓取一组类似的页面(网络漫画)。因为这些页面非常相似,所以我编写了一个名为ComicCrawler的类,其中包含所有spider逻辑和一些类变量(start_urlnext_selector,等等)。然后在每个spider的具体类中重写这些类变量。你知道吗

为每个漫画手动创建类是很麻烦的。我现在想在JSON文件中指定属性,并在运行时创建类(即应用工厂模式(?))我该怎么做?你知道吗

或者:有没有一种运行spider而不为其创建类的方法?编辑:核心问题似乎是Scrapy使用类,而不是实例作为其spider。否则我就把类变量变成实例变量,然后就可以了。你知道吗


示例:

class ComicSpider(Spider):
  name = None
  start_url = None
  next_selector = None
  # ...

  # this class contains much more logic than shown here

  def start_requests(self):
    # something including / along the lines of...
    yield Request (self.start_url, self.parse)

  def parse(self, response):
    # something including / along the lines of...
    yield Request(response.css(self.next_selector).get(), self.parse)

在另一个文件中:

class SupernormalStep(ComicSpider):
  name = "SupernormalStep"
  start_url = "https://supernormalstep.com/archives/8"
  next_selector = "a.cc-next"

我想要的是:

myComics = {
  "SupernormalStep": {
    "start_url": "https://supernormalstep.com/archives/8",
    "next_selector": "a.cc-next"
  }, # ...
}

process = CrawlerProcess(get_project_settings())
for name, attributes in myComics:
  process.crawl(build_process(name, attributes))

附言:我爬起来很负责。你知道吗


Tags: nameselfnoneurlparse页面processselector
2条回答

class语句是直接使用type的声明性包装。假设process.crawl将类作为参数

process = CrawlerProcess(get_project_settings())
for name, attributes in myComics.items():
    process.crawl(type(name, (ComicSpider,), attributes))

type(name, (ComicSpider,), attributes)将创建一个名为name的类,该类将从ComicSpider继承,并具有attributes字典中定义的属性。An example on Python docs.

查找元类。这是Python中动态创建新类的方法。What are metaclasses in Python?

对于这个更简单的情况,有一个更简单的方法,在chepner's answer中描述。你知道吗

相关问题 更多 >