import importlib.util import os import sys import threading import time import types print( sys.version_info ) PICK_API = int( os.environ[ "PICK_API" ] ) # 0: deprecated # 1: deprecated with `module_for_loader` # 2: new xxx_module = \ """ print( '=== loading module ===' ) import time time.sleep( 3 ) x = 0 print( '=== loaded module ===' ) """ class Loader( object ): def find_module( self, fullname, path ): if "xxx" == fullname: return self if PICK_API == 0: def load_module( self, fullname ): orig_module = sys.modules.get( fullname, None ) module = sys.modules[ fullname ] = orig_module or types.ModuleType( fullname ) try: exec( xxx_module, module.__dict__ ) except Exception: if not orig_module: del sys.modules[ fullname ] raise else: return module elif PICK_API == 1: @importlib.util.module_for_loader def load_module( self, module ): exec( xxx_module, module.__dict__ ) elif PICK_API == 2: def create_module( self, fullname ): pass def exec_module( self, module ): exec( xxx_module, module.__dict__ ) else: raise ValueError( "bad" ) sys.meta_path.insert( 0, Loader() ) def f(): time.sleep( 1 ) import xxx print( xxx.x ) t = threading.Thread( target=f ) t.daemon = True t.start() import xxx print( xxx.x ) t.join()