问题
I have set up a script with argparse that gives me the following NameSpace:
Namespace(action='list', input='all', target='domain')
I have made a few functions which are called according to the positionals, and at the moment I have a working situation by calling them with blurbs of code like this one:
if args.action == 'list':
if len(sys.argv) == 2:
parser.print_help()
sys.exit(0)
elif args.target == 'domain':
domain_list()
elif args.target == 'forwarding':
forwarding_list()
elif args.target == 'transport':
transport_list()
elif args.target == 'user':
user_list()
else:
all_list()
I know this can be done way, way better than this; but with my limited knowledge of Python, I can't seem to figure this one out.
Recap: I want something like, if at all possible (pseudocode)
if args.action == 'add':
target = args.target
target_add()
where target_add() is something like domain_add().
Thanks in advance!
回答1:
It sounds like action could be list or add, while target could be domain, forwarding, transport, or user. Yes, you would end up with a lot of if..then..else code if you had to manually list what each combination of options would do.
Here is a way to simplify this:
- Use itertools.product to generate all the possible combinations of options.
- Use a whitelist dispatch dict to map options to functions. The keys are 2-tuples, such as
('domain','list'), or('transport','add'). The values are the associated function objects.
import itertools as IT
targets = 'domain forwarding transport user'.split()
actions = 'list add'.split()
dispatch = {key:globals()['%s_%s' % key] for key in IT.product(targets, actions)}
# This calls the function specified by (target, action).
# The `dict.get` method is used so that if the key is not in `dispatch`, the `all_list` function is called.
dispatch.get((args.target, args.action), all_list)()
来源:https://stackoverflow.com/questions/14101989/using-positional-arguments-from-argparse-as-function-name