如何使用timeit.timeit测试多行Python代码且不出现EOL语法错误
解决timeit测试代码出现EOL错误的方案
报错根因
你将包含\n等转义字符的代码直接复制进普通三重引号字符串作为timeit的入参时,字符串解析逻辑会误将代码里的转义符和外层字符串的边界结合,导致解析到字符串末尾时没有找到匹配的引号,触发EOL(行尾扫描字符串字面量)错误。
最优解决方案:封装函数调用
完全避开字符串转义问题,后续修改代码也不需要重复复制粘贴,操作步骤如下:
- 把你的业务逻辑全部封装到一个独立函数中
- 直接将函数名作为参数传给
timeit.timeit即可
示例代码:
# 封装业务逻辑 def run_logic(): # 此处替换为你的实际输入读取逻辑,以下为示例模拟输入 input1 = ["2", "0 0 1 1 small", "3 2 6 5 large", "3", "2 0 small", "0.5 0.6 medium", "3 4 large", "3", "60.0 2.9 111.4 32.9 medium", "20.0 82.6 43.4 153.1 small", "34.7 9.6 56.6 78.2 large", "6", "60.0 8.3 small", "43.4 153.1 small", "13.4 55.9 medium", "61.5 68.1 medium", "72.1 69.1 large", "78.4 13.2 large", "0"] nm = [] peanut_descriptions = [] box_descriptions = [] for line in input1: next_line_index = input1.index(line)+1 parsed_line = line.split() # 读取每组用例的盒子/花生数量 if len(parsed_line) == 1: if int(parsed_line[0]) == 0: break nm.append(int(parsed_line[0])) # 解析花生描述 if len(parsed_line) == 3: peanut_description_dict = {'x': parsed_line[0], 'y': parsed_line[1], 'peanut_size': parsed_line[2]} peanut_descriptions.append(peanut_description_dict) # 解析盒子描述 if len(parsed_line) == 5: box_description_dict = {'x1': parsed_line[0], 'y1': parsed_line[1], 'x2': parsed_line[2], 'y2': parsed_line[3], 'intended_size': parsed_line[4]} box_descriptions.append(box_description_dict) previous_line = line # 提取花生尺寸列表 peanut_sizes = [] for i in peanut_descriptions: peanut_size = i['peanut_size'] peanut_sizes.append(peanut_size) # 拆分测试用例 cases = [] for i in range(len(nm)): if i % 2 != 0: continue boxes_index = nm[i] peanuts_index = nm[i+1] boxes_case = box_descriptions[0:boxes_index] peanuts_case = peanut_descriptions[0:peanuts_index] cases.append([boxes_case, peanuts_case]) del box_descriptions[0:boxes_index] del peanut_descriptions[0:peanuts_index] # 匹配逻辑 all_statuses = [] for case_index in range(len(cases)): case = cases[case_index] box = case[0] peanut = case[1] statuses = [] for p in range(len(peanut)): status = "floor" for b in range(len(box)): p_x = float(peanut[p]['x']) p_y = float(peanut[p]['y']) peanut_size = peanut[p]['peanut_size'] b_x1 = float(box[b]['x1']) b_y1 = float(box[b]['y1']) b_x2 = float(box[b]['x2']) b_y2 = float(box[b]['y2']) box_category = box[b]['intended_size'] if b_x1 <= p_x <= b_x2 and b_y1 <= p_y <= b_y2: status = box_category if peanut_size == box_category and status == box_category: status = "correct" statuses.append(status) all_statuses.append(statuses) # 生成输出 output1 = [] for i in range(len(all_statuses)): case_statuses = all_statuses[i] paragraph = "" for j in range(len(case_statuses)): line = peanut_sizes[j] + " " + case_statuses[j] + "\n" paragraph += line output1.append(paragraph) del peanut_sizes[0:len(case_statuses)] output1 = "\n".join(output1) # 性能测试时可注释print,避免IO耗时影响测试结果 # print(output1) # 性能测试 import timeit print(timeit.timeit(run_logic, number=100))
备选方案:使用原始字符串
如果你坚持要使用字符串传代码的方式,可以在外层三重引号前加r声明为原始字符串,Python会将字符串内所有转义符识别为普通字符,不会触发解析错误:
import timeit test1 = r""" # 把你的完整代码直接复制到此处即可 """ print(timeit.timeit(test1, number=100))
注意事项
- 性能测试时建议注释掉
print语句,避免IO操作占用过多时间导致测试结果不准 - 实际使用文件输入时,仅需将
run_logic函数内的input1替换为你读取文件生成列表的逻辑即可,无需修改测试框架
内容的提问来源于stack exchange,提问作者amab8901
相关产品推荐
相关产品推荐

