![](/img/trans.png)
[英]How do I dynamically create instances of all classes in a directory with python?
[英]How do you dynamically load python classes from a given directory?
如果我使用module/
的相應目錄定義模塊模塊 ,是否可以從子模塊(如a.py
或b.py
動態加載類?
--module
----a.py
----b.py
這需要知道要搜索的班級名稱嗎? 我可以設置一個基類,以某種方式加載這些孩子?
基本用例是允許用戶編寫程序將加載的自己的一些代碼。與rails允許您在某些目錄中編寫自己的控制器,視圖和模型的方式相同。
到目前為止我動態加載模塊的代碼是
def load(folder):
files = {}
for filename in os.listdir(folder):
if (filename[0] != '_' and filename[0] != '.'):
files[filename.rstrip('.pyc')] = None
# Append each module to the return list of modules
modules = []
mod = __import__(folder, fromlist=files.keys())
for key in files.keys():
modules.append(getattr(mod, key))
return modules
我希望修改它以返回類對象。
您正在尋找pkgutil.walk_packages
。 使用此功能,您可以執行以下操作:
def load(root_import_path, is_valid=lambda entity: True):
"""Returns modules in ``root_import_path`` that satisfy the ``is_valid`` test
:param root_import_path: An string name for importing (i.e. "myapp").
:param is_valid: A callable that takes a variable and returns ``True``
if it is of interest to us."""
prefix = root_import_path + u"."
modules = []
for _, name, is_pkg in walk_packages(root_import_path, prefix=prefix):
if is_pkg:
continue
module_code = __import__(name)
contents = dir(module_code)
for thing in contents:
if is_valid(thing):
modules.append(thing)
return modules
另外,如果你不介意接受依賴,你可以嘗試使用straight.plugin
加載器,這比這個簡單的load
函數復雜一點。
#!/usr/bin/env python
import os
import sys
import inspect
def load_modules_from_path(path):
"""
Import all modules from the given directory
"""
# Check and fix the path
if path[-1:] != '/':
path += '/'
# Get a list of files in the directory, if the directory exists
if not os.path.exists(path):
raise OSError("Directory does not exist: %s" % path)
# Add path to the system path
sys.path.append(path)
# Load all the files in path
for f in os.listdir(path):
# Ignore anything that isn't a .py file
if len(f) > 3 and f[-3:] == '.py':
modname = f[:-3]
# Import the module
__import__(modname, globals(), locals(), ['*'])
def load_class_from_name(fqcn):
# Break apart fqcn to get module and classname
paths = fqcn.split('.')
modulename = '.'.join(paths[:-1])
classname = paths[-1]
# Import the module
__import__(modulename, globals(), locals(), ['*'])
# Get the class
cls = getattr(sys.modules[modulename], classname)
# Check cls
if not inspect.isclass(cls):
raise TypeError("%s is not a class" % fqcn)
# Return class
return cls
def main():
load_modules_from_path('modules')
# load the TestClass1
class_name = load_class_from_name('class1.TestClass1')
# instantiate the Testclass1
obj = class_name()
# using this object obj to call the attributes inside the class
print obj.testclass1()
if __name__ == '__main__': main()
在模塊目錄內,我還有兩個用於測試的模塊:
[♫ test] modules :~ pwd
/tmp/dynamic_loader/modules
[♫ test] modules :~ ls -lR
total 32
-rw-r--r-- 1 staff staff 138 Aug 30 21:10 class1.py
-rw-r--r-- 1 staff staff 575 Aug 30 21:11 class1.pyc
-rw-r--r-- 1 staff staff 139 Aug 30 21:11 class2.py
-rw-r--r-- 1 staff staff 576 Aug 30 21:11 class2.pyc
[♫ test] modules cat class1.py
class TestClass1(object):
def testclass1(self):
print 'I am from testclass1'
def some_function():
print 'some function 1'
以下兩個模塊一起工作,做了類似的事情。 基本上,您可以使用dir()
模塊並檢查使用getattr
檢索的類的類類型。
http://code.google.com/p/pycopia/source/browse/trunk/QA/pycopia/QA/shellinterface.py
http://code.google.com/p/pycopia/source/browse/trunk/aid/pycopia/module.py
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.