如何修复字符串格式Python函数的语法问题?
问题描述
我有一个包含字符串格式Python函数的文本文件,代码会从中读取每个函数,传入对应参数后运行。目前使用以下代码片段运行文本文件中的函数字符串(例如fun_str):
dict = {} exec(fun_str, globals(), dict) f, = dict.values() f()
只要函数字符串符合Python标准语法(如缩进、换行等),代码就能正常运行。但如果读取到如下单行格式的函数字符串:
"def fun(list): output_list = [] for i in list: if i not in output_list: output_list.append(i) return output_list"
就会触发SyntaxError: invalid syntax错误,错误标记指向for关键字。请问是否有内置模块或方法可在通过exec运行前修复该函数字符串,使其符合标准语法?
解决方案
Python标准库中没有直接修复这类语法错误的内置模块,但可以通过以下两种可靠方法处理:
方法1:借助代码格式化库(推荐)
使用black这类专业的代码格式化工具(需额外安装),它能自动识别Python语法结构,为单行代码添加正确的换行和缩进。示例代码:
import black broken_fun_str = "def fun(list): output_list = [] for i in list: if i not in output_list: output_list.append(i) return output_list" # 移除字符串两端的引号(如果存在) if broken_fun_str.startswith(('"', "'")) and broken_fun_str.endswith(('"', "'")): broken_fun_str = broken_fun_str[1:-1] try: # 格式化代码 fixed_fun_str = black.format_str(broken_fun_str, mode=black.FileMode()) # 执行格式化后的函数 exec_dict = {} exec(fixed_fun_str, globals(), exec_dict) f = exec_dict['fun'] print(f([1,2,2,3])) # 输出: [1,2,3] except Exception as e: print(f"处理失败: {e}")
安装方式:执行pip install black即可。black会严格遵循PEP8规范,能处理绝大多数复杂的单行代码场景。
方法2:手动修复(适合简单场景)
如果不想依赖第三方库,可以针对单行函数的语法特征,手动在关键字前添加换行和缩进:
def fix_single_line_func(func_str): # 移除两端引号 if func_str.startswith(('"', "'")) and func_str.endswith(('"', "'")): func_str = func_str[1:-1] # 定义需要换行的关键字 target_keywords = ['for', 'if', 'return'] # 为每个关键字添加换行和缩进 for kw in target_keywords: func_str = func_str.replace(f' {kw}', f'\n {kw}') # 处理函数定义后的第一个缩进 func_str = func_str.replace(':', ':\n ', 1) # 处理嵌套语句的缩进(比如if内的语句) func_str = func_str.replace(': ', ':\n ') return func_str # 测试修复效果 broken_str = "def fun(list): output_list = [] for i in list: if i not in output_list: output_list.append(i) return output_list" fixed_str = fix_single_line_func(broken_str) print(fixed_str) # 输出格式化后的代码: # def fun(list): # output_list = [] # for i in list: # if i not in output_list: # output_list.append(i) # return output_list # 执行验证 exec_dict = {} exec(fixed_str, globals(), exec_dict) f = exec_dict['fun'] print(f([1,2,2,3])) # 输出: [1,2,3]
这种方法适合结构简单的单行函数,若遇到嵌套函数、复杂表达式等场景,可能需要扩展逻辑。
内容的提问来源于stack exchange,提问作者Bsh
相关产品推荐
相关产品推荐

