自动导入文件夹中的所有子模块然后调用相同的名称函数 - python runtime inspect相关 [英] auto import all sub modules in a folder then invoke same name functions - python runtime inspect related

查看:144
本文介绍了自动导入文件夹中的所有子模块然后调用相同的名称函数 - python runtime inspect相关的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的计算机上有一个打开的文件夹,

I have an open folder on my computer,

OpenFunctions\
    ____Template.py
    function1.py
    function2.py
    ......
    functionx.py

此文件夹是实验目的,用于扩展整个应用程序可以执行的功能。所以,让我们认为这是一个快速而干燥的尝试,在这种情况下没有安全考虑。

This folder is experimental purpose for extend the ability of the whole app can doing. So let’s just think it is a quick and dry trying, no security consideration in this case.

我的目的是,如果我放弃 functionx。 py ____ Template.py 之后,应用程序可以知道新功能是否可用,并将以某种方式调用此新连接文件中定义的函数 - 类似于插件系统,但应该有点不同。

My purpose is, if I drop a functionx.py following the ____Template.py, the app can know the new functions is available and will invoke the functions defined in this new joined file in someway – something like the plugin system, but should be a bit different.

所以我写了一个 ____ inspect.py 可能会让应用程序有能力知道已输入的内容。

So I wrote a ____inspect.py may let application have an ability to know what has been inputed.

这是

____inspect.py

def get_this_file_defined_functions(name_filter = "__"):
    import inspect, sys 
    f = inspect.getmembers(sys.modules[__name__], inspect.isfunction) 
    return [x for x in f if not x[0].startswith(name_filter)] 

def get_this_module_sub_modules(name_filter = "__"):
    import os.path, pkgutil
    pkgpath = os.path.dirname(__file__)
    m = [name for _, name, _ in pkgutil.iter_modules([pkgpath])] 
    return [x for x in m if not x[0].startswith(name_filter)]

def import_sub_modules_under_me(auto_exec_function = "auto_exec"):
    m = get_this_module_sub_modules()
    for i in m:  # need try except later
        exec "global %s; import %s" % (i, i)  
        #this will auto invoke __init__.py if sub modules folder is included
    for i in m:
        try:
            eval(i).eval(auto_exec_function)()
        except AttributeError:
            print "module %s has no function %s", % (i, auto_exec_function) 
        else:
            print "error on execute %s in module %s", % (auto_exec_function, i)

def execute_all_homonymy_functions(exec_function = "exec"):
    m = get_this_module_sub_modules()
    for i in m:
        #I need here for test if the module has been imported
        eval(i).eval(exec_function)()

这是

____Template.py

def __you_can_not_see_me(): pass  # because filtered by str.startswith()
def auto_exec(): pass             # this will be auto executed
def you_can_get_me(): pass
def you_can_get_me1(): pass
def you_can_get_me2(): pass

基于上述想法我还希望将结构扩展到以下

based on above idea I also want to extend structure to below

main.py
____inspect.py
OpenFunctions\
    __init__.py
    ____Template.py
    function1.py
    function2.py
    ......
    functionx.py
    module_aa
        \__init__.py
          aa.py
          aa1.py

这是 main.py __ init __。py 可能看起来像

import ____inspect
____inspect.import_sub_modules_under_me()
____inspect.execute_all_homonymy_functions("what_ever_i_want")

问题:


  1. __ init __ 代码将无法正常工作,因为 sys.modules [__ name __] 在调用时是 ____ inspect 而不是
    OpenFunctions module_aa 我想,是否有避免将 sys.modules [__ name __] 传递给上的 import_sub_modules_under_me() main.py __ init __。py

  1. Above __init__ code will not working, because the sys.modules[__name__] is ____inspect when invoking but not the OpenFunctions or module_aa I want, is there a way to avoid pass the sys.modules[__name__] to the import_sub_modules_under_me() on the main.py or the __init__.py?

我想 execute_all_homonymy_functions()将执行文件夹中的所有相同名称功能,无论它存在于子模块还是单个文件中,但我想调用所有和最新版本的case新模块添加或源已更改运行时。然后我想使用代码导入aa,重新加载(aa)但在下面的链接上可能被认为是错误的,有什么建议吗?
我在 _ _inspect.py

I suppose execute_all_homonymy_functions() will execute all the same name function in folder no matter it is exists in a sub module or in a single file, but I want to invoke all and the latest version in case the module new added or the source has been changed runtime. Then I want to use the code import aa, reload(aa) but may be thought as the wrong on below link, any suggestions? The issue I marked I need here for test if the module has been imported in __inspect.py

[http://stackoverflow.com/questions/5027352/how-to-test-if-one-python-module-has-been-imported]

[http://stackoverflow.com/questions/5027352/how-to-test-if-one-python-module-has-been-imported]

我还想在调用之前知道文件中一个函数的返回类型,建议在每个函数上附加一个装饰。所以我的计划是:

I also want to know the return type of one function in a file before invoking it, it was suggested to attach a decorate on each function. So my plan is:

\ n

____decorate.py

def attrs(**kwds):
     def decorate(f):
         for k in kwds:
             setattr(f, k, kwds[k])
         return f
     return decorate

functionx.py
import ../____decorate.py

@attrs(argument_types=(int, int,),returns=int)
def __you_can_not_see_me(): pass

@attrs(argument_types=(int, int,),returns=int)
def auto_exec(): pass             # I will be auto executed

@attrs(argument_types=(int, int,),returns=int)
def you_can_get_me(): pass

@attrs(argument_types=(int, int,),returns=int)
def you_can_get_me1(): pass

@attrs(argument_types=(int, int,),returns=int)
def you_can_get_me2(): pass

检查案例是否正常?还是有更好的解决方案?

Is it works ok for inspect case? Or there’s an better solution?

最后一个:代码

exec "global %s; import %s" % (i, i) 
eval(i).eval(auto_exec_function)()

看起来很难看,有两行以上的替代品吗?

looks ugly, any alternative for above two lines?

感谢您的帮助。

Rgs,
KC

Rgs, KC

推荐答案

首先解决您的上一个问题:在最新版本的Python中动态导入模块,使用 importlib.import_module(),这就是它的用途。如果您使用的是旧版本的Python,则应使用 __ import __ (但请检查文档中该直接方法的特性 - 这是<$ c $的原因c> import_module()添加了函数作为替换。)

To address your last question first: to dynamically import modules in recent versions of Python, use importlib.import_module(), that's what it is for. If you're on an older version of Python, you should use __import__ instead (but check the idiosyncracies of that direct approach in the docs - there's a reason the import_module() function was added as a replacement).

解决第一个问题:没有正式的可移植方式来检索信息关于调用函数的全局环境,所以最正确的答案是在需要的地方简单地传递 __ name __

To address your first question: there is no officially portable way to retrieve information about the calling function's global environment, so the most correct answer is to simply pass __name__ in as an argument wherever it is needed.

在Python中重新加载总是有点危险,因为在重新加载时并不是所有东西都能正常工作(如果重新加载它们,或者它们引用的模块,很多标准库模块都会失败)。

Reloading in Python is always a little dangerous, since not everything works correctly under reloading (even many standard library modules will fail if you reload either them, or a module they reference).

我真的建议花一些时间来探索Python中关于插件架构的现有问题的答案:构建一个最小的Python中的插件架构

I really suggest spending some time exploring the answers to this existing question about plugin architectures in Python: Building a minimal plugin architecture in Python

这篇关于自动导入文件夹中的所有子模块然后调用相同的名称函数 - python runtime inspect相关的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆