如何使用多态修改CsvToDatabase类with语句的open编码且不重复代码
方案解答
这种用继承扩展的实现思路是完全可行的,不需要重写with语句内部的多行业务代码,有两种成熟的实现方案可选:
方案1:无破坏性修改原类(推荐)
你可以对原类做向后兼容的调整,完全不会影响其他部门的现有使用:
- 把原类中写死的编码参数抽成类属性/luigi参数,默认保留原来的
utf-8,原有逻辑完全不变:
import luigi import csv class CsvToDatabase(luigi.Task): # 新增编码参数,默认值和原有硬编码保持一致,全兼容现有调用 file_encoding = luigi.Parameter(default='utf-8') def run(self): ## (...) with open(self.input().some_attribute, 'r', encoding=self.file_encoding) as some_dataframe: y = csv.reader(some_dataframe, delimiter=';') ### 原有多行处理代码完全不变 # (...)
- 你的子类只需要覆盖编码参数即可,不需要重写任何业务逻辑:
from script_of_interest import CsvToDatabase class LatinCsvToDatabase(CsvToDatabase): file_encoding = 'ISO-8859-1'
方案2:完全不修改原类
如果确实没有权限修改原类的代码,可以用临时替换内置open函数的方式实现编码替换,所有原类的业务逻辑完全复用:
from script_of_interest import CsvToDatabase import builtins class LatinCsvToDatabase(CsvToDatabase): def run(self): # 保存原生open函数 original_open = builtins.open # 自定义open函数,强制覆盖编码参数 def patched_open(*args, **kwargs): kwargs.pop('encoding', None) return original_open(*args, encoding='ISO-8859-1', **kwargs) # 临时替换内置open builtins.open = patched_open try: # 调用父类原有run逻辑 super().run() finally: # 恢复原生open,避免影响其他业务 builtins.open = original_open
内容的提问来源于stack exchange,提问作者Filippe O. Gonçalves
相关产品推荐
相关产品推荐

