继承argparse模块的Python类无法调用自身派生方法的问题排查
usage method Ah, I've run into this exact pitfall before! The issue isn't with subclassing in general—it's a name collision between your custom method and a built-in attribute of argparse.ArgumentParser.
Here's the breakdown:
- The base
argparse.ArgumentParserclass already has an instance attribute namedusage(it's a string that holds the usage text, orNoneif you don't set it). - When you define a method named
usagein yourMyParsersubclass, the base class's__init__method will overwrite this method with theusageattribute during instantiation. So by the time you try to callself.usage()in yourerrormethod,self.usageis no longer your method—it's a string (orNone), hence the "NoneType not callable" error.
Why your test class worked
Your testA class is a custom base class with no built-in usage attribute, so your usage method never gets overwritten. That's why it worked as expected.
The fix: Rename your custom method
The simplest solution is to pick a name for your usage-printing method that doesn't clash with the base class's attributes. As you discovered, renaming it to myusage works perfectly. You could also use something more descriptive like print_custom_usage to make your code clearer.
Code Examples
Broken code (name collision)
import subprocess import argparse import sys class MyParser(argparse.ArgumentParser): def usage(self): print "redispub.py -s 'started' -c 'ethandevelop-C1-G1' -m 'salt started' -e 'us-east-develop.onvamdev.com' -p 6379" print def error(self, message): sys.stderr.write('error: %s\n' % message) self._usage() self.__usage() self.usage() sys.exit(2)
Fixed code (renamed method)
import subprocess import argparse import sys class MyParser(argparse.ArgumentParser): def myusage(self): print "redispub.py -s 'started' -c 'ethandevelop-C1-G1' -m 'salt started' -e 'us-east-develop.onvamdev.com' -p 6379" print def error(self, message): sys.stderr.write('error: %s\n' % message) self.myusage() sys.exit(2)
Additional note
You mentioned someone suggested using the usage attribute directly instead of subclassing, but since you need to override the error method, that approach doesn't fit your use case. That's totally valid—subclassing to customize error is a perfectly reasonable approach, you just need to watch out for these hidden name conflicts!
内容的提问来源于stack exchange,提问作者tradetree

