簡體   English   中英

Python從模塊動態導入類

[英]Python import classes from modules dynamically

我正在使用具有許多子組件的API。 我正在制作一個與此API進行交互的工具包,因此我想使其能夠基於變量動態加載某些類,例如,加載內部設置了變量api_module = True的所有類。

.
├── APIModules
│   ├── ccu.py
│   ├── __init__.py
│   └── OpenAPI.py

ccu文件中的CCU類

class CCU:
    api_module = True
    actions    = ['post_new_purge','get_purge_queue','get_purge_status']

這將幫助我在添加更多類時動態記錄和擴展工具包,而不必每次添加新的子組件時都維護導入列表。 是否有捷徑可尋?

我知道我可以使用glob獲取APIModules目錄中所有python文件的列表,但是隨后我想加載並檢查文件中的所有類,而不知道它們可能被稱為什么。

import os
import glob
modules = glob.glob(os.path.dirname(__file__)+"/*.py")

由於您需要導入該類以讀取其屬性,並且試圖弄清楚是否應該首先導入它,因此這里有一個catch 22。

這樣,您便可以使用其他方法來解析.py文件,並根據該方法決定是否導入相關模塊。 但是這種方法也很混亂而且太復雜。

我認為,最簡單的方法是徹底改變觀點。 除了在每個模塊內部都沒有api_module = True ,您還可以在主應用程序內部只有一個活動模塊列表,然后根據該列表進行決定:

api_modules = ["module_1", "module_2", "module_3"]

這減少了維護量(您只需要維護一行代碼),並提供了相同的靈活性。

您可以將元類與類注冊表一起使用,以跟蹤添加到系統中的任何新類。

這里有一個演練,應該為您提供所需的幫助http://effbot.org/zone/metaclass-plugins.htm

這是否一個好主意是另一個問題(我認為sqlalchemy使用此模式作為聲明性基礎,並且效果很好)。

# from http://effbot.org/zone/metaclass-plugins.htm
registry = [] # list of subclasses

class Plugin(object):
    class __metaclass__(type):
        def __init__(cls, name, bases, dict):
            type.__init__(name, bases, dict)
            registry.append((name, cls))

# in your plugin modules
class SpamPlugin(Plugin):
    pass

class BaconPlugin(Plugin):
    pass

# in your plugin loader
# import all plugin modules

# loop over registered plugins
for name, cls in registry:
    if cls is not Plugin:
        print name, cls
        # here you could check various attributes of the class to
        # see if it was one you wanted to use

編輯我想我有點誤解了-您也不想一個接一個地導入模塊-但是您可以編寫一些內容來導入api文件夾中的所有文件。 然后,每個類都將從維護注冊表的基本API類繼承。 當您想使用任何東西時,請轉到注冊表以查找您感興趣的類。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM