函数名加一个约定的标志 带这个标志的就可以尝试当成函数解析 其实就是一个 switch case 就可以了
我理解的是你现在参数化里面有一块是 ${get_phone()},然后你用正则表达式把{}里面的这个 get_phone() 拿出来了,但是你想把这个提取出来的字符串当作函数执行是吧?
我这有个方法可以试下,你现在拿出来的 get_phone() 是个字符串类型的,你可以用 eval 再解包一次,因为你现在有这个函数,解包后应该就能识别出来了,我之前用过一次这样的方式,可行。
就是不知道怎么函数解析,只要凡是通过我这个正则提取出来就进行函数解析,问题是不知道怎么解析,怎么让 Python 知道他是一个函数呢
eval(“get_phone()”)
//参考一下 用 java 写的
// 从 ${}中匹配到的参数 如果是以__
开头则尝试进行函数匹配 这里的参数是 ${__yesterday(yyyy-MM-dd)}
Pattern matchFuncPattern = Pattern.compile("__(.+?\\(.*?\\))");
Matcher matcherFunc = matchFuncPattern.matcher(param);
while (matcherFunc.find()) {
String methodStr = matcherFunc.group(1);
String method = methodStr.substring(0, methodStr.indexOf("("));
//urlencode 函数直接使用整个methodParam,参数中有可能会带有逗号
String methodParam = methodStr.substring(methodStr.indexOf("(") + 1, methodStr.lastIndexOf(")"));
//其他函数使用逗号来区分多个参数
String[] methodParams = methodParam.split(",");
//funcValue用来存储内置函数生成的值
String funcValue = "";
switch (method.toLowerCase()) {
case "yesterday":
//使用函数生成的值替换占位符,这里是 2023-08-10
上面大佬说的
eval()
用 eval 简单点:
1、eval
def get_sum(a,b):
return a+b
s=eval('get_sum')(2,3)
print(s)
# 类中的方法
class myC:
def get_sum(self,a,b):
return a+b
s=eval('myC().get_sum')(1,2)
print(s)
2 如果类中也可以用 getattr 方法获取
class Context():
x=10
def get_name(self,*names):
for name in names:
print("hello "+name +"!")
def setattr_y(self):
setattr(self,"y",'yy')
c=Context()
# 带可变参数执行对象的方法
value="yq,ym,yy"
getattr(Context(),"get_name")(*value.split(','))
3、也可以通过 vars 从模块字典中取。
这种其实最适合让 GPT 回答
你可以尝试使用 Python 中的自动模块导入功能来更智能地管理函数的导入。Python 提供了importlib
模块,它可以在运行时动态地导入模块。这样你可以根据需要选择性地导入函数,而不需要提前手动导入整个模块。
下面是一个示例代码,演示了如何使用importlib
动态地导入函数:
import importlib
def execute_function(module_name, function_name, *args):
try:
module = importlib.import_module(module_name)
function = getattr(module, function_name)
return function(*args)
except (ImportError, AttributeError):
# 处理导入错误或函数不存在的情况
return None
# 以调用模块A中的函数func1为例
result = execute_function('moduleA', 'func1', arg1, arg2)
if result is not None:
# 执行成功
print(result)
else:
# 函数不存在或导入失败
print("函数不存在或导入失败")
在上面的示例中,execute_function
函数接受一个模块名、函数名以及所需的参数。它使用importlib.import_module
来动态地导入名为module_name
的模块,然后使用getattr
函数从该模块中获取名为function_name
的函数。然后,你可以执行该函数,并处理可能的导入错误和函数不存在的情况。
通过使用importlib
模块,你可以更灵活地处理函数导入,并根据需要选择性地导入特定的函数,而无需手动导入整个模块。
要让 Python 识别并执行函数,你可以使用eval()
函数或者exec()
语句。这两个功能强大但也潜在地危险,因为它们可以执行任意的 Python 代码。确保你从可信任的源头获取函数名和代码,避免安全风险。
下面是一个示例代码,展示了如何使用re
模块和eval()
函数来解析 YAML 文件,并执行函数:
import re
# 假设这是你的 YAML 用例
yaml_content = """
- name: 接口测试
endpoint: /api/xyz
data:
phone: ${get_phone()}
"""
# 假设这是你的自定义函数
def get_phone():
# 执行获取手机号的逻辑,并返回
phone_number = "1234567890"
return phone_number
# 使用正则表达式匹配函数名
pattern = re.compile(r"\${([\w_]+)\(\)}")
# 替换函数调用为实际的返回值
def replace_func(match):
# 获取函数名
func_name = match.group(1)
# 根据函数名执行函数并返回结果
result = eval(func_name) # 使用 eval() 执行函数
return str(result)
# 替换函数调用为实际的返回值
replaced_yaml = re.sub(pattern, replace_func, yaml_content)
print(replaced_yaml)
在上面的示例中,我们首先定义了一个get_phone()
函数来获取手机号。然后,我们使用正则表达式和re
模块来匹配${get_phone()}
这样的函数调用,并使用eval()
函数执行函数并替换调用。
请注意,上面的示例只是一个简单的示范,你可能需要根据自己的具体需求进行调整。另外,使用eval()
函数或者exec()
语句需要谨慎,确保只执行可信任的代码。
感谢大佬的不吝赐教,本人还有一个疑问:
用例 yaml 中只能提取到方法名 ${get_phone()},那模块名从哪里来呢
我只能想到在 yaml 中这么写 ${moduleA.get_phone()},
提取到内容后 moduleA.get_phone(),分解出模块名和函数名
是的,你的理解是正确的。在解析用例 YAML 文件时,你可以将模块名和函数名都包含在参数中,例如 ${moduleA.get_phone()}
。
在解析用例时,你可以通过正则表达式或其他方法提取出 ${moduleA.get_phone()}
,然后对其进行解析和分解得到模块名和函数名。
以下是一个示例代码,演示了如何解析 ${moduleA.get_phone()}
并执行对应的函数:
import re
# 解析并执行函数
def execute_function(module_name, function_name, *args):
# 模拟执行函数的逻辑
result = f"Executing {module_name}.{function_name} with arguments: {args}"
return result
# 原始用例内容
test_case = """
api: /user/register
data:
mobile: ${moduleA.get_phone()}
name: John Doe
"""
# 使用正则表达式匹配并提取函数调用
regex_pattern = r'\$\{(.+?)\}'
matches = re.findall(regex_pattern, test_case)
# 遍历匹配结果,解析模块名和函数名,并执行对应的函数
for match in matches:
module_function = match.strip()
module_name, function_name = module_function.split('.', 1) # 分解模块名和函数名
function_args = () # 如果需要传参,可以解析参数列表
function_result = execute_function(module_name, function_name, *function_args) # 执行函数
test_case = test_case.replace(f"${{{module_function}}}", function_result)
print(test_case)
在这个示例中,我们将 ${moduleA.get_phone()}
作为函数调用的格式,解析出模块名和函数名。然后,我们调用 execute_function()
来执行对应的函数。
需要注意的是,这里只是一个简单的示例,假设函数的模块名是固定的。如果模块名是动态的,你可能需要根据实际情况进行相应的调整。另外,对于函数参数也可以在解析时进行进一步处理,以满足你的需求。
在这种情况下,你需要在解析 YAML 文件的时候,根据需要执行的函数名称来确定所需导入的模块。可以通过预先定义一个映射关系,将函数名称与对应的模块进行关联。
以下是一个示例代码,演示了如何根据函数名动态导入模块并执行对应的函数:
import re
import importlib
# 解析并执行函数
def execute_function(module_name, function_name, *args):
# 动态导入模块
module = importlib.import_module(module_name)
# 获取函数对象
function = getattr(module, function_name)
# 执行函数
result = function(*args)
return result
# 原始用例内容
test_case = """
api: /user/register
data:
mobile: ${moduleA.get_phone()}
name: John Doe
"""
# 使用正则表达式匹配并提取函数调用
regex_pattern = r'\$\{(.+?)\}'
matches = re.findall(regex_pattern, test_case)
# 遍历匹配结果,解析模块名和函数名,并执行对应的函数
for match in matches:
module_function = match.strip()
module_name, function_name = module_function.split('.', 1) # 分解模块名和函数名
function_args = () # 如果需要传参,可以解析参数列表
function_result = execute_function(module_name, function_name, *function_args) # 执行函数
test_case = test_case.replace(f"${{{module_function}}}", function_result)
print(test_case)
在这个示例中,我们使用 importlib.import_module()
方法根据模块名动态导入模块。然后,我们使用 getattr()
方法获取函数对象,并执行该函数。
需要注意的是,这里使用的是动态导入模块的方式,你需要确保模块名是可靠的、可信任的,并且模块包含了需要调用的函数。另外,对于函数的参数也可以在解析时进行进一步处理,以满足你的需求。
可以用反射