通过字符串导入 Python 模块的方法详解

yipeiwu_com6年前Python基础

我们平时导入第三方模块的时候,一般使用的是 import 关键字,例如:

import scrapy
from scrapy.spider import Spider

但是如果各位同学看过 Scrapy 的 settings.py 文件,就会发现里面会通过字符串的方式来指定pipeline 和 middleware,例如:

DOWNLOADER_MIDDLEWARES = {
   'Test.middlewares.ExceptionRetryMiddleware': 545,
   'Test.middlewares.BOProxyMiddlewareV2': 543,
 }
 
 SPIDER_MIDDLEWARES = {
  'Test.middlewares.LoggingRequestMiddleware': 543,
 }

我们知道,这里的 Test.middlewares.ExceptionRetryMiddleware 实际上对应了根目录下面的 Test 文件夹里面的 middlewares.py 文件中的 ExceptionRetryMiddleware 类。那么 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 函数:

首先根据字符串路径最右侧的 . 把字符串路径分成两个部分,例如: Test.middlewares.LoggingRequestMiddleware 分成 Test.middlewares 和 LoggingRequestMiddleware

使用 import_module 导入左边的部分

从左边部分通过 getattr 获得具体的类

现在我们来测试一下。我们创建的测试文件结构如下图所示:

 

其中, pipelines.py 文件的内容如下图所示:

  

main.py 文件的内容如下图所示:

 

运行 main.py ,可以看到 pipelines.py 中的 Pipeline 类被成功执行了,如下图所示:

 

总结

以上所述是小编给大家介绍的通过字符串导入 Python 模块的方法详解,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

相关文章

浅谈Python中列表生成式和生成器的区别

列表生成式语法: [x*x for x in range(0,10)] //列表生成式,这里是中括号 //结果 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81...

如何安装并使用conda指令管理python环境

一、动机 最近打算折腾vn.py,但只有py27版本的,因为一向习惯使用最新稳定版的,所以不得不装py27的环境,不得不说 Python的全局锁真的很烦。 身为懒癌患者,必然使用...

Django 登陆验证码和中间件的实现

Django 登陆验证码和中间件的实现

验证码 在用户注册、登陆页面为了防止暴力请求,可以加入验证码。如果验证码错误,则不需要继续处理,可以减轻服务器的压力 使用验证码也是一种有效防止 csrf 的方法 def veri...

python3+PyQt5实现使用剪贴板做复制与粘帖示例

python3+PyQt5实现使用剪贴板做复制与粘帖示例

本文是对《Python Qt GUI快速编程》的第10章的例子剪贴板用Python3+PyQt5进行改写,分别对文本,图片和html文本的复制与粘帖,三种做法大同小异。 #!/usr...

如何将python中的List转化成dictionary

如何将python中的List转化成dictionary

问题1:如何将一个list转化成一个dictionary? 问题描述:比如在python中我有一个如下的list,其中奇数位置对应字典的key,偶数位置为相应的value 解决方案:...