如何合并Django文件上传功能中的文本提取方法?
问题描述
我开发了一个具备文件上传功能的Django应用,有两个用于提取文本的方法:
def filter_verdi_total_number_fruit(self, file_name): self.extractingText.extract_text_from_image(file_name) regex = r"(\d*(?:\.\d+)*)\s*\W+(?:" + '|'.join(re.escape(word) for word in self.extractingText.list_fruit) + ')' return re.findall(regex, self.extractingText.text_factuur_verdi[0]) def filter_verdi_fruit_name(self, file_name): self.extractingText.extract_text_from_image(file_name) regex = r"(?:\d*(?:\.\d+)*)\s*\W+(" + '|'.join(re.escape(word) for word in self.extractingText.list_fruit) + ')' return re.findall(regex, self.extractingText.text_factuur_verdi[0])
这两个方法存在大量重复代码:都接收file_name参数、重复调用extract_text_from_image、正则结构仅捕获组位置不同,最终都通过re.findall返回结果。
我尝试合并为一个方法:
def combine_methods(self, file_name): self.filter_verdi_total_number_fruit(file_name) self.filter_verdi_fruit_name(file_name)
在views.py中调用时:
if uploadfile.image.path.endswith('.pdf'): content = '\n'.join(filter_text.combine_methods(uploadfile.image.path))
出现错误:
can only join an iterable Exception Location: C:\Users\engel\Documents\NVWA\software\blockchainfruit\main\views.py, line 50, in post Raised during: main.views.ReadingFile
错误原因
combine_methods没有返回值(默认返回None),而str.join()要求传入可迭代对象(如列表、元组),None不满足要求,因此报错。- 原两个方法重复调用
extract_text_from_image(file_name),会导致文件被重复处理,浪费性能。
解决方案
方案1:返回合并后的可迭代结果
修改combine_methods,仅调用一次文件提取,同时返回可直接用于join的结果:
def combine_methods(self, file_name): # 仅调用一次文件提取,避免重复处理 self.extractingText.extract_text_from_image(file_name) fruit_pattern = '|'.join(re.escape(word) for word in self.extractingText.list_fruit) # 提取数字 number_regex = r"(\d*(?:\.\d+)*)\s*\W+(?:{})".format(fruit_pattern) numbers = re.findall(number_regex, self.extractingText.text_factuur_verdi[0]) # 提取水果名称 name_regex = r"(?:\d*(?:\.\d+)*)\s*\W+({})".format(fruit_pattern) names = re.findall(name_regex, self.extractingText.text_factuur_verdi[0]) # 返回数字与名称配对的列表 return [f"{num}: {name}" for num, name in zip(numbers, names)]
调用处无需修改,直接使用join即可。
方案2:返回两个结果的元组(按需处理)
如果需要分别处理数字和名称,可返回元组,在调用处自行拼接:
def combine_methods(self, file_name): self.extractingText.extract_text_from_image(file_name) fruit_pattern = '|'.join(re.escape(word) for word in self.extractingText.list_fruit) number_regex = r"(\d*(?:\.\d+)*)\s*\W+(?:{})".format(fruit_pattern) numbers = re.findall(number_regex, self.extractingText.text_factuur_verdi[0]) name_regex = r"(?:\d*(?:\.\d+)*)\s*\W+({})".format(fruit_pattern) names = re.findall(name_regex, self.extractingText.text_factuur_verdi[0]) return numbers, names
调用处修改为:
if uploadfile.image.path.endswith('.pdf'): numbers, names = filter_text.combine_methods(uploadfile.image.path) content_lines = [f"{num} {name}" for num, name in zip(numbers, names)] content = '\n'.join(content_lines)
额外优化:提取公共正则片段
进一步减少冗余,把重复的正则片段提取为单独变量:
def combine_methods(self, file_name): self.extractingText.extract_text_from_image(file_name) escaped_fruits = [re.escape(word) for word in self.extractingText.list_fruit] fruit_pattern = '|'.join(escaped_fruits) number_match = re.findall(r"(\d*(?:\.\d+)*)\s*\W+(?:{})".format(fruit_pattern), self.extractingText.text_factuur_verdi[0]) name_match = re.findall(r"(?:\d*(?:\.\d+)*)\s*\W+({})".format(fruit_pattern), self.extractingText.text_factuur_verdi[0]) return list(zip(number_match, name_match))
调用时:
if uploadfile.image.path.endswith('.pdf'): paired_results = filter_text.combine_methods(uploadfile.image.path) content = '\n'.join([f"{num} {name}" for num, name in paired_results])
内容的提问来源于stack exchange,提问作者mightycode Newton
相关产品推荐
相关产品推荐

