简体   繁体   English

Python将目录中文件的所有功能导入一个名称空间

[英]Python import all functions from files within a directory into one namespace

I'm trying to make an __init__.py file which will import all functions from *.py files from a directory into a namespace (the directory's name). 我正在尝试制作__init__.py文件,该文件将从目录中* .py文件中的所有功能导入目录中的命名空间(目录名称)。 The logic is shown below: 逻辑如下所示:

for f in os.listdir(wd):
    if not f.endswith('.py') or f == '__init__.py':
        continue
    names = get_public_functions(open(wd + f))
    try:
        mod = __import__(f[:-3], fromlist=names)
        for fn in names:
            fun = getattr(mod, fn)
            setattr(sys.modules[__name__], fn, fun)
    except Exception as e: 
        for fn in names:
            setattr(sys.modules[__name__], fn, lambda: str(e))

So, you can observe that if there are syntax error in a file, the functions will still be imported, but they will return the syntax error (as a string). 因此,您可以观察到,如果文件中存在语法错误,这些函数仍将被导入,但是它们将返回语法错误(作为字符串)。

What's frustrating, is that when there are syntax errors in multiple files, while I'm expecting something like: 令人沮丧的是,当多个文件中存在语法错误时,我期望的是:

mymodule.fn() => error1,
mymodule.fn2() => error1 (these were from the first file),
mymodule.fn3() => error2 etc.

I get only the last error message. 我仅收到最后一条错误消息。 I think the error must be in the except block, but I can't figure it. 我认为该错误一定是在except块中,但我无法弄清楚。 Can anyone help? 有人可以帮忙吗?

You need to bind the value of e to the scope of the lambda you create. 您需要将e的值绑定到您创建的lambda的范围。 Or rather, you want to bind the str(e) result to the lambda: 或者,您想将str(e)结果绑定到lambda:

error = str(e)
for fn in names:
    setattr(sys.modules[__name__], fn, lambda error=error: error

Now each lambda has a keyword parameter storing the then-current value of error . 现在,每个lambda都有一个关键字参数,用于存储error的当前值。 Because the error parameter is a keyword parameter with a default value, your lambdas still work when called with arguments. 由于error参数是具有默认值的关键字参数,因此在使用参数调用时,lambda仍然有效。

The alternative would be to create a new function scope: 替代方法是创建一个新的函数范围:

def errorfunction(error):
    return lambda: error

error = str(e)
for fn in names:
    setattr(sys.modules[__name__], fn, errorfunction(error)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM