基本上,我想加载特定模块的所有函数(如果存在)并将它们与类方法合并。如果我在__module__
内部构建了__new__
类,我可以直接构建模块并导入它。我正在寻找一个get_module_fns
来解决我的问题。我希望做的事情如下:
get_module_fns('pathto.mod1.toimport')
如果存在,则会将所有函数作为dict返回。
这是代码和测试的link。
# mtcl.py
import inspect
import imp
def get_module_fns(module_name, module_path):
try:
mod_loaded = imp.load_source(module_name, module_path)
module_fns = [(name, func) for name, func in
inspect.getmembers(mod_loaded, inspect.isfunction)]
except FileNotFoundError as e:
return {}
except ImportError as e:
return {}
return dict(module_fns)
class GetModuleFunctions(type):
def __new__(cls, name, bases, namespaces, **kwargs):
module_functions = get_module_fns('toimport', './toimport.py')
namespaces.update(module_functions)
new_class = super(GetModuleFunctions, cls).__new__(
cls, name, bases, namespaces)
new_class._mdl_fns = module_functions
return new_class
class ClassBase(metaclass=GetModuleFunctions):
def __init__(self, *args, **kwargs):
super(ClassBase, self).__init__(*args, **kwargs)
@property
def module_functions(self):
return self.__class__._mdl_fns
# mod0.py
from .mtcl import ClassBase
class M0(ClassBase):
def function_m0(self):
return 0
# mod1/__init__.py
from ..mtcl import ClassBase
class M1(ClassBase):
def function_m1(self):
return 1
# mod1/toimport.py
def function_1(obj, *args, **kwargs):
return 1
# mod1/mod2/__init__.py
from ...mtcl import ClassBase
class M2(ClassBase):
def function_m2(self):
return 2
# mod1/mod2/toimport.py
def function_2(obj, *args, **kwargs):
return 2
答案 0 :(得分:1)
尝试以下方法:
import inspect
import importlib
def get_module_fns(cls, module_name):
try:
mod_loaded = importlib.import_module(
'%s.%s' % (cls.__module__, module_name)
)
module_fns = [(name, func) for name, func in
inspect.getmembers(mod_loaded, inspect.isfunction)]
except ModuleNotFoundError as e:
return {}
except ImportError as e:
return {}
return dict(module_fns)
class GetModuleFunctions(type):
def __new__(cls, *args, **kwargs):
new_class = super(GetModuleFunctions, cls).__new__(
cls, *args, **kwargs)
module_functions = get_module_fns(new_class, 'toimport')
for name, fn in module_functions.items():
setattr(new_class, name, fn)
new_class._mdl_fns = module_functions
return new_class
由于您正在查找类模块中的模块,因此应该这样做:
mod_loaded = importlib.import_module(
'%s.%s' % (cls.__module__, module_name)
)
可悲的是,您无法在namespace
之后使用__new__.super
:
for name, fn in module_functions.items():
setattr(new_class, name, fn)