如何經過字符串導入 Python 模塊

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

  1. 首先根據字符串路徑最右側的.把字符串路徑分紅兩個部分,例如:Test.middlewares.LoggingRequestMiddleware分紅Test.middlewaresLoggingRequestMiddleware
  2. 使用import_module導入左邊的部分
  3. 從左邊部分經過getattr得到具體的類

如今咱們來測試一下。咱們建立的測試文件結構以下圖所示:函數

其中,pipelines.py文件的內容以下圖所示:測試

main.py文件的內容以下圖所示:spa

運行main.py,能夠看到pipelines.py中的Pipeline類被成功執行了,以下圖所示:code

相關文章
相關標籤/搜索