咱们平时导入第三方模块的时候,通常使用的是import
关键字,例如:python
import scrapy
from scrapy.spider import Spider
复制代码
可是若是各位同窗看过 Scrapy 的settings.py
文件,就会发现里面会经过字符串的方式来指定pipeline 和 middleware,例如:git
DOWNLOADER_MIDDLEWARES = {
'Test.middlewares.ExceptionRetryMiddleware': 545,
'Test.middlewares.BOProxyMiddlewareV2': 543,
}
SPIDER_MIDDLEWARES = {
'Test.middlewares.LoggingRequestMiddleware': 543,
}
复制代码
咱们知道,这里的Test.middlewares.ExceptionRetryMiddleware
实际上对应了根目录下面的Test
文件夹里面的middlewares.py
文件中的ExceptionRetryMiddleware
类。那么 Scrapy 是如何根据这个字符串,导入这个类的呢?github
在 Scrapy 源代码中,咱们能够找到相关的代码:scrapy
def load_object(path):
"""Load an object given its absolute object path, and return it. object can be a class, function, variable or an instance. path ie: 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware' """
try:
dot = path.rindex('.')
except ValueError:
raise ValueError("Error loading object '%s': not a full path" % path)
module, name = path[:dot], path[dot+1:]
mod = import_module(module)
try:
obj = getattr(mod, name)
except AttributeError:
raise NameError("Module '%s' doesn't define any object named '%s'" % (module, name))
return obj
复制代码
根据这段代码,咱们知道,它使用了importlib
模块的import_module
函数:ide
.
把字符串路径分红两个部分,例如:Test.middlewares.LoggingRequestMiddleware
分红Test.middlewares
和LoggingRequestMiddleware
import_module
导入左边的部分getattr
得到具体的类如今咱们来测试一下。咱们建立的测试文件结构以下图所示:函数
其中,pipelines.py
文件的内容以下图所示:测试
main.py
文件的内容以下图所示:spa
运行main.py
,能够看到pipelines.py
中的Pipeline
类被成功执行了,以下图所示:code