自动导入文件夹中的所有子模块然后调用相同的名称函数 - python runtime inspect相关 [英] auto import all sub modules in a folder then invoke same name functions - python runtime inspect related
问题描述
我的计算机上有一个打开的文件夹,
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")
问题:
-
__ init __
代码将无法正常工作,因为sys.modules [__ name __]
在调用时是____ inspect
而不是
OpenFunctions
或module_aa
我想,是否有避免将sys.modules [__ name __]
传递给上的
或import_sub_modules_under_me()
main.py__ init __。py
?
Above
__init__
code will not working, because thesys.modules[__name__]
is____inspect
when invoking but not theOpenFunctions
ormodule_aa
I want, is there a way to avoid pass thesys.modules[__name__]
to theimport_sub_modules_under_me()
on themain.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屋!