83 lines
2.4 KiB
Python
83 lines
2.4 KiB
Python
#!/usr/bin/env python
|
||
# coding=utf-8
|
||
|
||
"""
|
||
@author: chen wei
|
||
@Software: PyCharm
|
||
@contact: t6i888@163.com
|
||
@file: templates.py
|
||
@date: 2024 2024/9/22 22:20
|
||
@desc:
|
||
"""
|
||
import copy
|
||
import logging
|
||
import re
|
||
import string
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
def _str(s) -> str:
|
||
# 将数据转换为str类型。
|
||
return f"'{s}'"
|
||
|
||
|
||
class Template(string.Template):
|
||
"""
|
||
1,支持函数调用
|
||
2,参数也可以是变量
|
||
"""
|
||
func_mapping = {
|
||
"str": _str,
|
||
"int": int,
|
||
"float": float,
|
||
"bool": bool
|
||
} # 内置函数有的,直接放入mapping;内置函数没有的,在funcs中定义,自动放入mapping
|
||
|
||
call_pattern = re.compile(r"\${(?P<func_name>.*?)\((?P<func_args>.*?)\)}")
|
||
|
||
def render(self, mapping: dict) -> str:
|
||
s = self.safe_substitute(mapping) # 原有方法替换变量
|
||
s = self.safe_substitute_funcs(s, mapping)
|
||
|
||
return s
|
||
|
||
def safe_substitute_funcs(self, template, mapping) -> str:
|
||
"""
|
||
解析字符串中的函数名和参数,并将函数调用结果进行替换
|
||
:param template: 字符串
|
||
:param mapping: 上下文,提供要使用的函数和变量
|
||
:return: 替换后的结果
|
||
"""
|
||
mapping = copy.deepcopy(mapping)
|
||
mapping.update(self.func_mapping) # 合并两个mapping
|
||
|
||
def convert(mo):
|
||
func_name = mo.group("func_name")
|
||
func_args = mo.group("func_args").split(",")
|
||
func = mapping.get(func_name) # 读取指定函数
|
||
func_args_value = [mapping.get(arg, arg) for arg in func_args]
|
||
|
||
if func_args_value == [""]: # 处理没有参数的func
|
||
func_args_value = []
|
||
|
||
if not callable(func):
|
||
return mo.group() # 如果是不可调用的假函数,不进行替换
|
||
else:
|
||
return str(func(*func_args_value)) # 否则用函数结果进行替换
|
||
|
||
return self.call_pattern.sub(convert, template)
|
||
|
||
|
||
def hot_load():
|
||
from commons import funcs
|
||
for func_name in dir(funcs): # 遍历模块中的所有函数
|
||
if func_name.startswith("_"):
|
||
continue
|
||
func_code = getattr(funcs, func_name) # 取到函数对象
|
||
if callable(func_code): # 如果是一个可以调用的函数
|
||
Template.func_mapping[func_name] = func_code # 函数放到Template中
|
||
|
||
|
||
hot_load()
|