Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何动态加载python模块并对每个模块调用方法?_Python_Design Patterns_Architecture - Fatal编程技术网

如何动态加载python模块并对每个模块调用方法?

如何动态加载python模块并对每个模块调用方法?,python,design-patterns,architecture,Python,Design Patterns,Architecture,这里是Python初学者。假设我有三种方法来抓取网站。让我们把它们称为scrape_site_a、scrape_site_b和scrape_site_c。我想运行其中的每一个,但我想以这样一种方式定义它们,即我可以动态调用它们,而无需按名称调用它们。理想情况下,我希望加载目录中的所有模块,并对每个模块调用相同的方法。到目前为止,我的尝试如下: 地点a.py 站点_b.py 现场检查 我有_init__uuuuy.py设置,可以执行以下操作: 擦伤 我想做一些类似的事情: for site in

这里是Python初学者。假设我有三种方法来抓取网站。让我们把它们称为scrape_site_a、scrape_site_b和scrape_site_c。我想运行其中的每一个,但我想以这样一种方式定义它们,即我可以动态调用它们,而无需按名称调用它们。理想情况下,我希望加载目录中的所有模块,并对每个模块调用相同的方法。到目前为止,我的尝试如下:

地点a.py

站点_b.py

现场检查

我有_init__uuuuy.py设置,可以执行以下操作:

擦伤

我想做一些类似的事情:

for site in sites:
    site.scrape()
我意识到这里有一个我不理解的基本编程概念,我有两个问题:

有没有办法用我正在采取的方法做到这一点? 有更好的方法吗?为什么? 我想这可能是你想要的

from sites import *
for item in globals():
    if item.startswith("site_") and hasattr(globals()[item],'scrape'):
       globals()[item].scrape()

像这样的内省有点冒险。。。reader Ware

以下程序扫描给定目录,加载其中的每个.py文件,并调用模块的scrape方法(如果存在)

from os import listdir
from os.path import join

scraper_dir = "./scrapers"

for scraper_name in listdir(scraper_dir):
    if scraper_name.endswith(".py"):
        with open(join(scraper_dir, scraper_name)) as scraper_file:
            scraper_globals = {}              # this will hold scraper's globals
            scraper_module = exec(scraper_file.read(), scraper_globals)
            if "scrape" in scraper_globals:   # we have a scrape method
                scrape_method = scraper_globals["scrape"]
                callable(scrape_method) and scrape_method()    # call it
你会想用这个模块来做这样的事情

进口检验 modules=[mod for mod in globals if inspect.ismoduleevalmod]
将为您提供命名空间中的所有模块。如果需要,您应该能够看到如何将其修改为更具体。诀窍是运行eval将名称字符串转换为对某个对象的引用,该对象可能是一个模块。

这很接近,但我希望它是动态的。理想情况下,我希望加载目录中的所有模块,并在每个模块中调用一个方法,每个方法都有相同的名称。我已经更新了我的问题,以便更清楚地了解如何使用类作为名称填充而不是模块。您要寻找的是类似于OSGi的东西,但它太大了,无法一次性解释。这个答案有点粗糙,但确实有效。
from sites import *

site_a.scrape()
site_b.scrape()
site_c.scrape()
for site in sites:
    site.scrape()
from sites import site_a,site_b,site_c
sites = [site_a,site_b,site_c]
for site in sites:
    site.scrape()
from sites import *
for item in globals():
    if item.startswith("site_") and hasattr(globals()[item],'scrape'):
       globals()[item].scrape()
from os import listdir
from os.path import join

scraper_dir = "./scrapers"

for scraper_name in listdir(scraper_dir):
    if scraper_name.endswith(".py"):
        with open(join(scraper_dir, scraper_name)) as scraper_file:
            scraper_globals = {}              # this will hold scraper's globals
            scraper_module = exec(scraper_file.read(), scraper_globals)
            if "scrape" in scraper_globals:   # we have a scrape method
                scrape_method = scraper_globals["scrape"]
                callable(scrape_method) and scrape_method()    # call it