简体   繁体   中英

Sublcassing argparse and overriding add_argument_group

I want to use a generic parser for multiple scripts, so to keep code cleaner I want to have one place where all the common arguments can be handled. I can do this by subclassing ArgumentParser, but I've run into the problem of adding groups. When I add a group, they no longer have access to the custom methods I wrote. To get around this, I've basically copied the add_argument_group method and added the additional functions. I know this is a terrible solution, any advice for how to properly achieve this?

class CustomParser(argparse.ArgumentParser):
    def __init__(self, *args, **kwrds):
        super(CustomParser, self).__init__(*args, **kwrds)

    def add_enzyme(self):
        self.add_argument('--enzyme', help="The enzyme to cleave with. Also valid is a"
                                           " cleavage pattern such as [KR]|{P}.",
                          choices=protein_config.ENZYMES.keys(), type=str, default='trypsin')

    def add_fasta(self, help="The fasta file to operate on."):
        self.add_argument('-f', '--fasta', nargs='?', help=help, type=argparse.FileType('r'), default=sys.stdin)

    def add_out(self, help='The file to write results to. Leave blank for stdout,'):
        self.add_argument('-o', '--out', nargs='?', help=help, type=argparse.FileType('w'), default=sys.stdout)

    def add_argument_group(self, *args, **kwargs):
        group = argparse._ArgumentGroup(self, *args, **kwargs)
        self._action_groups.append(group)
        group.add_enzyme = self.add_enzyme
        group.add_fasta = self.add_fasta
        group.add_out = self.add_out
        return group

I would add the group-methods dynamically like this:

from types import MethodType

class CustomParser(argparse.ArgumentParser):
    def __init__(self, *args, **kwrds):
        super(CustomParser, self).__init__(*args, **kwrds)

    def add_argument_group(self, *args, **kwargs):

        def add_enzyme(self):
            self.add_argument(
                 '--enzyme',
                 help="The enzyme to cleave with. Also valid is a"
                 " cleavage pattern such as [KR]|{P}.",
                 choices=protein_config.ENZYMES.keys(), type=str, default='trypsin')

        def add_fasta(self, help="The fasta file to operate on."):
            self.add_argument(
                '-f', '--fasta', nargs='?', help=help, type=argparse.FileType('r'),
                default=sys.stdin)

        def add_out(self, help='The file to write results to. Leave blank for stdout,'):
            self.add_argument(
                '-o', '--out', nargs='?', help=help, type=argparse.FileType('w'),
                default=sys.stdout)

        group = super(CustomParser, self).add_argument_group(*args, **kwargs)
        setattr(group, add_enzyme.__name__, MethodType(add_enzyme, group, type(group)))
        setattr(group, add_fasta.__name__, MethodType(add_fasta, group, type(group)))
        setattr(group, add_out.__name__, MethodType(add_out, group, type(group)))

        #self._action_groups.append(group)

        return group

Think that works, can't really test since I don't have your dependencies. And hope that was what you needed. I commented out the call to self._action_groups.append since I'm guessing it wont be needed due to proper super call.

Have you tried using a parents parser?

import argparse

parent = argparse.ArgumentParser(add_help=False)
group = parent.add_argument_group('standard')
group.add_argument('--enzyme', help="The enzyme to cleave with")
group.add_argument('-f', '--fasta', nargs='?', help='help')
group.add_argument('-o', '--out', nargs='?',type=argparse.FileType('w'))

parser = argparse.ArgumentParser(parents=[parent])
parser.add_argument('--custom')
parser.print_help()

produces

usage: stack21938846.py [-h] [--enzyme ENZYME] [-f [FASTA]] [-o [OUT]]
                        [--custom CUSTOM]

optional arguments:
  -h, --help            show this help message and exit
  --custom CUSTOM

standard:
  --enzyme ENZYME       The enzyme to cleave with
  -f [FASTA], --fasta [FASTA]
                        help
  -o [OUT], --out [OUT]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM