咱們平時導入第三方模塊的時候,通常使用的是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