2017-03-29 12 views
1

基本的には、特定のモジュール(存在する場合)のすべての関数を読み込み、それらをクラスメソッドとマージしたいと思います。 __new__の内部に構築されているクラスの__module__があれば、モジュールに直接パスを作成してインポートできます。私は問題を解決するためにget_module_fnsを探しています。私は次のようなことをしたい:メタクラスの__new__内のモジュールを発見する際の問題

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 

答えて

1

Trと以下Y:

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) 
) 

悲しいことに、あなたは__new__.supernamespaceを使用することはできません。

for name, fn in module_functions.items():     
    setattr(new_class, name, fn) 
関連する問題