已有字符串形式的函数名称,那么如何调用这个函数呢?
通过调用内置函数locals()和globals()返回的字典对象,就可以可以获得名称与对象的映射关系。其中,locals()仅在全局范围内调用时可以获得函数对象。 我们来看以下的例子。
#函数cmd_help,返回提示字符串
def cmd_help():
return "This is demo funtion."
# 函数cmd_sum, 返回所有整数的和。
def cmd_sum(*nargs):
sum = 0
for num in nargs:
sum+=int(num)
return sum
# 函数名前缀cmd_
prefix = "cmd_"
# 将函数名与函数对象对应,并调用函数。这里省略了异常处理。
def dispatch(cmd,*nargs):
return globals()[prefix+cmd](*nargs)
#调用dispatch("help"), 输出结果:help: This is demo funtion.
print("help:", dispatch("help"))
#调用dispatch("sum",1,2,3),输出结果:sum(1,2,3)= 6
print("sum(1,2,3)=", dispatch("sum",1,2,3))
需要注意的是,使用上述方法通过字符串调用函数时,为了系统的安全,防止执行任意函数,需要对函数名做一些处理,也就是使用统一的前缀为这些函数命名。例如在上述例子中,使用前缀cmd_+函数名的形式定义函数(cmd_help,cmd_sum)。
在传入函数名字符串时,只传入函数名的后半部分(如"help","sum"),由程序添加前缀后组成完整的函数名,再调用该函数。
对于类的成员函数,则可以使用getattr()获得类成员函数。
class DemoClass:
prefix = "cmd_"
def cmd_help(self):
return "This is demo funtion."
def cmd_sum(self,*nargs):
sum = 0
for num in nargs:
sum+=int(num)
return sum
# 将函数名与类函数对应,并调用函数。省略了异常处理。
def dispatch(obj,cmd,*nargs):
return getattr(obj,obj.prefix+cmd)(*nargs)
demo_obj = DemoClass()
#调用dispatch(demo_obj,"help"), 输出结果:help: This is demo funtion.
print("help:", dispatch(demo_obj,"help"))
#调用dispatch(demo_obj,"sum",1,2,3),输出结果:sum(1,2,3)= 6
print("sum(1,2,3)=", dispatch(demo_obj,"sum",1,2,3))
上述代码通过字符串调用了类成员函数,与前一段代码执行的结果相同。
此外,还可以使用字典将字符串与函数对应起来调用,缺点就是每增加一个函数需要相应在字典对象中添加相应的键值,增加代码维护工作量。
以上代码在Python 3.6以上运行通过。