自定义Argparse的store_true动作并添加依赖参数检查的问题
CheckedStoreTrue Action Is Failing Ah, I see the exact issue here! The problem comes down to the order in which argparse parses arguments and runs custom actions. Let me break it down:
When you define your --save_files argument (using the custom CheckedStoreTrue action) before defining --out_dir and --files_to_save, argparse processes --save_files first. Even if you include --out_dir in your command line, argparse hasn't gotten around to parsing that argument yet—so namespace.out_dir is still its default None value when your custom action runs. That's why the error pops up even when you've provided the required parameter.
Two Fixes to Solve This
Fix 1: Adjust Argument Order (Quick Solution)
Move the --save_files argument definition after --out_dir and --files_to_save. This way, when argparse processes --save_files, the other parameters will already have been parsed and stored in the namespace:
import argparse class CheckedStoreTrue(argparse._StoreTrueAction): def __call__(self, parser, namespace, values, option_string=None): if not namespace.out_dir: parser.error("Please provide an output dir when using --save_files!") if not namespace.files_to_save: parser.error("Please provide --files_to_save when using --save_files!") setattr(namespace, self.dest, True) # Note: store_true uses True, not 'values' prs = argparse.ArgumentParser() # Add dependent arguments first prs.add_argument( "--out_dir", required=False, help="Directory to save files to." ) prs.add_argument( "--files_to_save", required=False, type=int, help="Number of files to save." ) # Add --save_files last prs.add_argument( "--save_files", action=CheckedStoreTrue, required=False, help="Enable file saving (requires --out_dir and --files_to_save)." ) args = prs.parse_args()
Fix 2: Validate After Parsing (More Reliable)
Custom actions are designed for handling individual parameter logic, not cross-parameter validation. A cleaner, more robust approach is to use a standard store_true action, then check your conditions after all arguments are parsed. This avoids relying on argument order entirely:
import argparse prs = argparse.ArgumentParser() prs.add_argument( "--save_files", action="store_true", required=False, help="Enable file saving (requires --out_dir and --files_to_save)." ) prs.add_argument( "--out_dir", required=False, help="Directory to save files to." ) prs.add_argument( "--files_to_save", required=False, type=int, help="Number of files to save." ) args = prs.parse_args() # Validate after parsing if args.save_files: if not args.out_dir: prs.error("Please provide --out_dir when using --save_files!") if not args.files_to_save: prs.error("Please provide --files_to_save when using --save_files!")
This second approach is generally preferred because it keeps your validation logic separate and makes the code easier to maintain.
内容的提问来源于stack exchange,提问作者tastyminerals

