遇到一个根据字符串名称调用 Python 方法的问题,考虑了几种可行的方式(函数名字符串+元组字符串 + 字典字符串,或者直接使用带参函数名字符串)。
1 函数名 字符串 + [参数元组 字符串] + [参数字典 字符串]
class TestClass:
@staticmethod
def test_method(x, y, z):
print(x, y, z)
# 方式 1, 反射
from ast import literal_eval
def call_method(str_method, str_args, str_kw):
getattr(TestClass, str_method)(*literal_eval(str_args), **literal_eval(str_kw))
call_method('test_method', '(2,3)', "{'z':4}")
# 方式 2,methodcaller
# 使用 operator.methodcaller(str_method,*args,**kw)(classname), 不细述
# 不安全的方式:简单粗暴使用 eval
2 带参 函数名 字符串 / 函数名 字符串 + [参数 字符串]
class TestClass:
@staticmethod
def test_method(x, y, z):
print(x, y, z)
# 方式 1,解析参数
import re
from ast import literal_eval
def call_method(str_method_with_param):
str_method, str_param = str_method_with_param.split('(', 1)[:-1] # 或正则
re_kw = re.search(r'([^,\'\"]*=.*)', str_param)
if re_kw:
list_kw = (kv.split('=', maxsplit=1) for kv in re_kw[0].strip(',').split(','))
kw = {k:literal_eval(v) for k,v in list_kw}
args = literal_eval(str_param.rstrip(re_kw[0]))
else:
kw = {}
if str_param and not str_param.endswith(','):
str_param += ','
args = literal_eval(str_param)
getattr(TestClass, str_method)(*args, **kw)
call_method('test_method(2,3,z=4)')
# 不安全的方式:简单粗暴使用 eval('TestClass.' + method_with_param)
<推广> 本站使用 NameSilo 提供的域名服务。