如何将字符串作为对象传递给 getattr python
How to pass a string as an object to getattr python
我有许多函数需要从各种导入文件中调用。
函数的格式如下:
a.foo
b.foo2
a.bar.foo4
a.c.d.foo5
并且它们作为原始字符串传递到我的脚本中。
我正在寻找一种干净的方法 运行 这些,带参数,并获得 return 值
现在我有一个混乱的系统,可以拆分字符串然后将它们提供给正确的 getattr 调用,但这感觉有点笨拙并且非常不可扩展。有没有一种方法可以将 getattr 的对象部分作为字符串传递?或者其他一些方法?
import a, b, a.bar, a.c.d
if "." in raw_script:
split_script = raw_script.split(".")
if 'a' in raw_script:
if 'a.bar' in raw_script:
out = getattr(a.bar, split_script[-1])(args)
if 'a.c.d' in raw_script:
out = getattr(a.c.d, split_script[-1])(args)
else:
out = getattr(a, split_script[-1])(args)
elif 'b' in raw_script:
out = getattr(b, split_script[-1])(args)
试试这个:
def lookup(path):
obj = globals()
for element in path.split('.'):
try:
obj = obj[element]
except KeyError:
obj = getattr(obj, element)
return obj
请注意,这将处理以任何全局名称开头的路径,而不仅仅是您的 a
和 b
导入模块。如果对向函数提供不受信任的输入有任何可能的担忧,您应该从包含允许起点的字典开始,而不是整个全局字典。
很难从你的问题中判断出来,但听起来你有一个命令行工具你 运行 作为 my-tool <function> [options]
。您可以像这样使用 importlib
,避免大多数 getattr
调用:
import importlib
def run_function(name, args):
module, function = name.rsplit('.', 1)
module = importlib.import_module(module)
function = getattr(module, function)
function(*args)
if __name__ == '__main__':
# Elided: retrieve function name and args from command line
run_function(name, args)
我有许多函数需要从各种导入文件中调用。
函数的格式如下:
a.foo
b.foo2
a.bar.foo4
a.c.d.foo5
并且它们作为原始字符串传递到我的脚本中。
我正在寻找一种干净的方法 运行 这些,带参数,并获得 return 值
现在我有一个混乱的系统,可以拆分字符串然后将它们提供给正确的 getattr 调用,但这感觉有点笨拙并且非常不可扩展。有没有一种方法可以将 getattr 的对象部分作为字符串传递?或者其他一些方法?
import a, b, a.bar, a.c.d
if "." in raw_script:
split_script = raw_script.split(".")
if 'a' in raw_script:
if 'a.bar' in raw_script:
out = getattr(a.bar, split_script[-1])(args)
if 'a.c.d' in raw_script:
out = getattr(a.c.d, split_script[-1])(args)
else:
out = getattr(a, split_script[-1])(args)
elif 'b' in raw_script:
out = getattr(b, split_script[-1])(args)
试试这个:
def lookup(path):
obj = globals()
for element in path.split('.'):
try:
obj = obj[element]
except KeyError:
obj = getattr(obj, element)
return obj
请注意,这将处理以任何全局名称开头的路径,而不仅仅是您的 a
和 b
导入模块。如果对向函数提供不受信任的输入有任何可能的担忧,您应该从包含允许起点的字典开始,而不是整个全局字典。
很难从你的问题中判断出来,但听起来你有一个命令行工具你 运行 作为 my-tool <function> [options]
。您可以像这样使用 importlib
,避免大多数 getattr
调用:
import importlib
def run_function(name, args):
module, function = name.rsplit('.', 1)
module = importlib.import_module(module)
function = getattr(module, function)
function(*args)
if __name__ == '__main__':
# Elided: retrieve function name and args from command line
run_function(name, args)