tensorflowのLazyLoaderからpythonのimportlibについて

14664 ワード

LayzerLoaderから
pythonのmoduleは、import,importlibの3つの方法でimportingを行うことができる.import_module(), __import__.
import文は、指定したモジュールを最初に検索し、検索結果を現在の役割ドメインにバインドする2つの操作を組み合わせています.
import()は直接呼び出され、モジュールの検索が実行され、見つかったときにモジュールの作成が行われます.例:
 module2 = __import__ ("data.api")

 print(module2.__dict__)
 """
    {'__name__': 'data', '__doc__': None, '__package__': 'data', '__loader__': <_frozen_importlib_external._namespaceloader object="" at="">, '__spec__': ModuleSpec(name='data', loader=<_frozen_importlib_external._namespaceloader object="" at="">, submodule_search_locations=_NamespacePath(['/Users/wuyongyu/PycharmProjects/untitled1/data', '/Users/wuyongyu/PycharmProjects/untitled1/data'])), '__file__': None, '__path__': _NamespacePath(['/Users/wuyongyu/PycharmProjects/untitled1/data', '/Users/wuyongyu/PycharmProjects/untitled1/data']), 'api': }

 """
#     :TypeError: 'module' object is not subscriptable
 api_instance = module2["api"].classA()

#     
api_instance = module2.api.classA()

importlibモジュールは、インポートシステムと対話するための豊富なAPIを提供します.importlib.import_module()は、組み込みよりも__を提供します.import__()より推奨され、より簡単なAPIは、呼び出しインポートメカニズムを開始するために使用される.
tensorflowではLazyerLoaderが定義されています
importlibでmoduleをインポートし、moduleの_を取得します.dict__属性に含まれる内容.moduleのメソッドやクラスを実際に使用する場合は、_getattr__ロードに対応するメソッドまたはクラスを取得します.
import unittest
import types
import importlib
import sys

class testModules(unittest.TestCase):
    # 1    types.ModuleType
    def test_Test_subclass(self):
        #      ModuleType     module
        m = types.ModuleType("m")
        class Hello(object):
            def hello(self):
                pass
        def function1():
            print("this is function 1")
        #  module     __dict__   ,  class   fucntion
        m.test_class = Hello
        m.test_function = function1

        #     module getattr     
        a = m.test_class()
        a.hello()
        m.test_function()

    # ModuleType    module       import
    #    module     sys.module     
    def test_Test_import_ModuleType(self):
        m = types.ModuleType("m")

        class Hello(object):
            def hello(self):
                pass
        def function1():
            print("this is function 1")
        m.test_class = Hello
        m.test_function = function1
        sys.modules["m"] = m
        import m as mm
        mm.test_function()


# tensorflow LazyLoader
class LazyLoader(types.ModuleType):
    """ Layz   Module ,   module    """
    def __init__(self, local_name, parent_module_globals, name):
        self._local_name = local_name
        self._parent_module_globals = parent_module_globals
        super(LazyLoader, self).__init__(name)

    def _load(self):
        """  module,      parent_module  """
        print("LazyLoader->_load")
        module = importlib.import_module(self.__name__)
        self._parent_module_globals[self._local_name] = module
        #  module      LazyLoader
        self.__dict__.update(module.__dict__)
        return module

    #   import_module  module  
    def __getattr__(self, item):
        print("LazyLoader->__getatrr__ item:", item)
        module = self._load()
        # print("type(module):", type(module))
        return getattr(module, item)

    def __dir__(self):
        module = self._load()
        return dir(module)

    def __reduce__(self):
        return __import__, (self.__name__,)

    def test(self):
        print("this is test attr")

if __name__ == '__main__':
    # unittest.main()
    _module = LazyLoader("m", globals(), "data.api") #   api _module    globals()
    sys.modules.setdefault("hh", _module)       #        hh    _module

    #      LazyLoader   ,    ,   __getattr__   module   
    getattr(globals()["_module"], "test")()
    w = getattr(globals()["_module"], "__name__")

    import hh      #    sys.module.setdefault      import,         _load
    hh.api()       #    __getattr__    _load     api