Python OOP场景下argparse自定义Action触发函数执行问题求助
解决方案
现有代码核心错误点
- 传参格式错误:
add_argument的action参数要求传入继承argparse.Action的子类,你当前直接写action=self.getcolors()是直接调用函数并传入返回值,完全不符合要求,且会导致函数提前执行报错。 - 初始化顺序倒置:
__init__方法中先执行参数解析,此时self.data还未初始化,getcolors方法中访问self.data会直接抛出属性不存在的错误。 - 逻辑时序错误:颜色过滤逻辑依赖解析后的参数和加载完成的数据集,你把过滤逻辑嵌入参数解析阶段,此时数据集还未加载,逻辑不可能正常运行。
方案1:按需求使用自定义Action实现
argparse的自定义Action必须继承argparse.Action基类,且实现固定参数的__call__方法,业务逻辑需放在参数解析、数据加载完成后触发,正确实现如下:
import argparse import re # 自定义Action类 class ColorFilterAction(argparse.Action): def __call__(self, parser, namespace, values, option_string=None): # 存储用户传入的color参数值到命名空间 setattr(namespace, self.dest, values) class UserSearch: def __init__(self) -> None: # 第一步:解析参数 self.args = self.get_args() # 第二步:加载数据集 self.data = ItemData(domains[self.args.type], self.args.name).output() # 第三步:指定了color参数就自动执行过滤 self.user_selection = self.getcolors() if self.args.color else [] def get_args(self): parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter) # 补全你原代码用到的type、name参数 parser.add_argument("-t", "--type", required=True, help="Item type") parser.add_argument("-n", "--name", required=True, help="Item name") parser.add_argument( "-c", "--color", help="Color of the item you want to search for.", default=[], nargs="*", # 传入Action类,不要加括号,argparse会自动完成实例化 action=ColorFilterAction, ) return parser.parse_args() def getcolors(self): user_selection = [] for k in self.args.color: sregex = re.compile(fr".*{k}.*", re.I | re.U) for item in self.data: for color_name in item["color"].keys(): if sregex.search(color_name): user_selection.append(item) # 匹配到就跳出循环,避免同一个item重复添加 break return user_selection
方案2:更简化的实现(无需自定义Action)
如果没有强制要求必须用自定义Action,你的需求完全可以省略自定义Action的步骤,用默认参数存储逻辑即可,代码更简洁易维护:
import argparse import re class UserSearch: def __init__(self) -> None: self.args = self.get_args() self.data = ItemData(domains[self.args.type], self.args.name).output() self.user_selection = self.getcolors() if self.args.color else [] def get_args(self): parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter) parser.add_argument("-t", "--type", required=True, help="Item type") parser.add_argument("-n", "--name", required=True, help="Item name") parser.add_argument( "-c", "--color", help="Color of the item you want to search for.", default=[], nargs="*", ) return parser.parse_args() def getcolors(self): user_selection = [] for k in self.args.color: sregex = re.compile(fr".*{k}.*", re.I | re.U) for item in self.data: for color_name in item["color"]: if sregex.search(color_name): user_selection.append(item) break return user_selection
内容的提问来源于stack exchange,提问作者user16725386
相关产品推荐
相关产品推荐

