Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从从列表中读取文件名和函数名的不同文件调用函数_Python_Arrays_Function - Fatal编程技术网

Python 从从列表中读取文件名和函数名的不同文件调用函数

Python 从从列表中读取文件名和函数名的不同文件调用函数,python,arrays,function,Python,Arrays,Function,我有多个函数存储在不同的文件中,文件名和函数名都存储在列表中。在没有条件语句的情况下,是否有调用所需函数的选项? 例如,file1有函数function11和function12 文件2具有函数function21和function22 我有名单 file_name = ["file1", "file2", "file1"] function_name = ["function12", "function22", "funciton12"] 我将从不同的函数中获取列表索引,基于此,我需要调用该

我有多个函数存储在不同的文件中,文件名和函数名都存储在列表中。在没有条件语句的情况下,是否有调用所需函数的选项? 例如,file1有函数function11和function12

文件2具有函数function21和function22

我有名单

file_name = ["file1", "file2", "file1"]
function_name = ["function12", "function22", "funciton12"]

我将从不同的函数中获取列表索引,基于此,我需要调用该函数并获取输出。

如果另一个函数将直接为您提供列表索引,那么您不需要将函数名作为字符串处理。而是直接存储,而不调用列表中的函数:

import file1, file2

functions = [file1.function12, file2.function22, file1.function12]
一旦你有了索引,就给他们打电话:

function[index]()
有一些方法可以实现Python中所谓的反射,并从字符串获取匹配的命名函数。但它们解决的问题比您描述的更高级,而且更困难,尤其是当您还必须使用模块名称时

如果您有允许从配置文件调用的函数和模块的白名单,但仍需要按字符串查找它们,则可以使用dict显式创建映射:

allowed_functions = {
    'file1': {
        'function11': file1.function11,
        'function12': file1.function12
    },
    'file2': {
        'function21': file2.function21,
        'function22': file2.function22
    }
}
然后调用函数:

try:
    func = allowed_functions[module_name][function_name]
except KeyError:
    raise ValueError("this function/module name is not allowed")
else:
    func()
最高级的方法是,如果需要从作者创建的插件模块加载代码。您可以使用标准库importlib包使用字符串名称查找要作为模块导入的文件,并动态导入它。它看起来像:

from importlib.util import spec_from_file_location, module_from_spec

# Look for the file at the specified path, figure out the module name
# from the base file name, import it and make a module object.
def load_module(path):
    folder, filename = os.path.split(path)
    basename, extension = os.path.splitext(filename)
    spec = spec_from_file_location(basename, path)
    module = module_from_spec(spec)
    spec.loader.exec_module(module)
    assert module.__name__ == basename
    return module
这仍然是不安全的,因为它可以在文件系统的任何地方查找模块。最好是自己指定文件夹,并且只允许在配置文件中使用文件名;但是,您仍然需要使用以下方法来防止黑客攻击路径:。。和/在文件名中

我有一个这样的项目。它从用户控制的白名单中选择路径,因此我必须警告我的用户不要相互信任路径白名单文件。我还搜索目录中的模块,然后制作一个可能使用的插件白名单,只基于目录中的插件-所以没有有趣的游戏。。。我还是担心我忘了什么

一旦有了模块名,就可以按名称从中获取函数,如:

dynamic_module = load_module(some_path)
try:
    func = getattr(dynamic_module, function_name)
except AttributeError:
    raise ValueError("function not in module")

无论如何,没有理由评估任何东西,或者根据用户输入生成和导入代码。这是最不安全的。

如果另一个函数将直接为您提供列表索引,那么您不需要将函数名作为字符串处理。而是直接存储,而不调用列表中的函数:

import file1, file2

functions = [file1.function12, file2.function22, file1.function12]
一旦你有了索引,就给他们打电话:

function[index]()
有一些方法可以实现Python中所谓的反射,并从字符串获取匹配的命名函数。但它们解决的问题比您描述的更高级,而且更困难,尤其是当您还必须使用模块名称时

如果您有允许从配置文件调用的函数和模块的白名单,但仍需要按字符串查找它们,则可以使用dict显式创建映射:

allowed_functions = {
    'file1': {
        'function11': file1.function11,
        'function12': file1.function12
    },
    'file2': {
        'function21': file2.function21,
        'function22': file2.function22
    }
}
然后调用函数:

try:
    func = allowed_functions[module_name][function_name]
except KeyError:
    raise ValueError("this function/module name is not allowed")
else:
    func()
最高级的方法是,如果需要从作者创建的插件模块加载代码。您可以使用标准库importlib包使用字符串名称查找要作为模块导入的文件,并动态导入它。它看起来像:

from importlib.util import spec_from_file_location, module_from_spec

# Look for the file at the specified path, figure out the module name
# from the base file name, import it and make a module object.
def load_module(path):
    folder, filename = os.path.split(path)
    basename, extension = os.path.splitext(filename)
    spec = spec_from_file_location(basename, path)
    module = module_from_spec(spec)
    spec.loader.exec_module(module)
    assert module.__name__ == basename
    return module
这仍然是不安全的,因为它可以在文件系统的任何地方查找模块。最好是自己指定文件夹,并且只允许在配置文件中使用文件名;但是,您仍然需要使用以下方法来防止黑客攻击路径:。。和/在文件名中

我有一个这样的项目。它从用户控制的白名单中选择路径,因此我必须警告我的用户不要相互信任路径白名单文件。我还搜索目录中的模块,然后制作一个可能使用的插件白名单,只基于目录中的插件-所以没有有趣的游戏。。。我还是担心我忘了什么

一旦有了模块名,就可以按名称从中获取函数,如:

dynamic_module = load_module(some_path)
try:
    func = getattr(dynamic_module, function_name)
except AttributeError:
    raise ValueError("function not in module")

无论如何,没有理由评估任何东西,或者根据用户输入生成和导入代码。这是最不安全的。

我不能100%确定我是否理解这种需要。也许问题会更详细

你在找这样的东西吗

m = ["os"]
f = ["getcwd"]
command = ''.join([m[0], ".", f[0], "()"])
# Put in some minimum sanity checking and sanitization!!!
if ";" in command or <other dangerous string> in command:
        print("The line '{}' is suspicious. Will not run".format(command))
        sys.exit(1)
print("This will error if the method isnt imported...")
print(eval(''.join([m[0], ".", f[0], "()"])) )

正如@KarlKnechtel所指出的,从外部文件输入命令是一个巨大的安全风险

我不能100%确定我是否理解这种需要。也许问题会更详细

你在找这样的东西吗

m = ["os"]
f = ["getcwd"]
command = ''.join([m[0], ".", f[0], "()"])
# Put in some minimum sanity checking and sanitization!!!
if ";" in command or <other dangerous string> in command:
        print("The line '{}' is suspicious. Will not run".format(command))
        sys.exit(1)
print("This will error if the method isnt imported...")
print(eval(''.join([m[0], ".", f[0], "()"])) )
正如@KarlKnechtel所指出的,命令来自外部
l文件是一个巨大的安全风险

另一种选择。然而,这并不比评估更安全

有权访问您从配置文件读取的列表的人可能会在您导入的列表中插入恶意代码

代码:

输出:


另一种选择。然而,这并不比评估更安全

有权访问您从配置文件读取的列表的人可能会在您导入的列表中插入恶意代码

代码:

输出:



我将从配置文件中获取列表,我不能这样存储!哦,那么这个问题应该提出来。还有:谁将创建配置文件?如果您不希望调用的文件名函数可能不是来自您自己的代码,而是来自标准库,则存在潜在的安全风险,如果我以任何格式将sys.exit放入配置文件中,我将生成配置文件,但是我不能更改配置文件,其他功能依赖于itI,我添加了更多的方法来实现。请小心,只允许用户使用您真正需要的电源。您不会在一行中获得此信息。我将从配置文件中获取列表,我不能这样存储!哦,那么这个问题应该提出来。还有:谁将创建配置文件?如果您不希望调用的文件名函数可能不是来自您自己的代码,而是来自标准库,则存在潜在的安全风险,如果我以任何格式将sys.exit放入配置文件中,我将生成配置文件,但是我不能更改配置文件,其他功能依赖于itI,我添加了更多的方法来实现。请小心,只允许用户使用您真正需要的权限。您不会在一行中获得此权限。如何将参数传递给使用此权限的用户?您提到您从两个列表中获取导入名称。文件名=[file1,file2,file1]和函数名=[function12,function22,function12]。这也是我上面提到的,除了我为module调用了file_name m,这是文件名的正确术语。我为函数调用了函数名f:我仍然郑重建议在运行任何从外部输入派生的命令之前添加一些健全性检查和输入健全性。请参见我的另一个答案。我不是从外部文件获取导入名称,我将只获取函数名以及它位于哪个文件中。谢谢,无需更改任何内容,我得到了我的评论的答案。如何使用此函数传递参数?您提到您从两个列表中获取导入名称。文件名=[file1,file2,file1]和函数名=[function12,function22,function12]。这也是我上面提到的,除了我为module调用了file_name m,这是文件名的正确术语。我为函数调用了函数名f:我仍然郑重建议在运行任何从外部输入派生的命令之前添加一些健全性检查和输入健全性。请参见我的另一个答案。我不是从外部文件获取导入名称,我只会得到函数名和它所在的文件。谢谢你,不需要更改任何东西,我得到了我的评论的答案。