首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用argparse解析"mount style“选项

使用argparse解析"mount style“选项
EN

Stack Overflow用户
提问于 2020-07-13 18:01:15
回答 1查看 45关注 0票数 1

在python中解析"mount style“选项的最佳选项是什么?

我需要解析与特定参数关联的argument=value列表,如以下示例所示:

代码语言:javascript
复制
myprogram --database type=mysql,user=root,passwd=secret,database=mydb --mail type=imap,server=imap.my.domain,user=myself,passwd=othersecret,port=999 --whatever key=val,key=val2,etcetera

我的第一个猜测是指定一个参数,然后手动解析它(仅限示例代码):

代码语言:javascript
复制
from argparse import ArgumentParser

parser = ArgumentParser(description='Example only')
parser.add_argument('-D', '--database', nargs=1)
parser.add_argument('-M', '--mail', nargs=1)
parser.add_argument('-W', '--whatever', nargs=1)

args = parser.parse_args('--database type=mysql,user=root,passwd=secret,database=mydb --mail type=imap,server=imap.my.domain,user=myself,passwd=othersecret,port=999 --whatever key=val,key=val2,etcetera'.split())

def parse(a):
    d = {}
    for x in a.split(','):
        try:
            k, v = x.split('=')
        except ValueError:
            k = x
            v = None
        d[k] = v
    
args.database = parse(args.database)
args.mail = parse(args.mail)
args.whatever = parse(args.whatever)

..。但我想知道有没有更好的方法。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-14 22:01:14

事实证明,处理这个问题的正确方法是实现一个自定义的argparse.Action

在特定情况下,这是合理工作的东西:

代码语言:javascript
复制
!/bin/env python3

from argparse import ArgumentParser, Action


class KeypairAction(Action):
    def __init__(self, option_strings, dest, keys=None, **kwargs):
        super().__init__(option_strings, dest, **kwargs)
        if keys is None:
            raise ValueError('must define "keys" argument')
        if isinstance(keys, dict):
            self.keys = keys
        elif isinstance(keys, (list, tuple)):
            self.keys = {}
            for k in keys:
                if isinstance(k, tuple):
                    k, v = k
                else:
                    v = None
                self.keys[k] = v

    def __call__(self, parser, namespace, values, option_string=None):
        d = {}
        for x in values.split(','):
            try:
                k, v = x.split('=')
            except ValueError:
                k = x
                v = None
            d[k] = v
        setattr(namespace, self.dest, d)


ap = ArgumentParser(description="My nice program")
ap.add_argument('-D', '--database', action=KeypairAction, keys=('type', 'host', 'port', 'user', 'pass', 'db'))
ap.add_argument('-M', '--mail', action=KeypairAction, keys=('type', 'host', 'port', 'user', 'pass'))
ap.add_argument('-W', '--whatever', action=KeypairAction, keys=('key1', 'key2', 'key3', 'etcetera'))

args = ap.parse_args('--database type=mysql,user=root,pass=secret,db=mydb '
                         '--mail type=imap,host=imap.my.domain,user=myself,pass=othersecret,port=999 '
                         '--whatever key1=val,key2=val2,etcetera'.split())
print(args)

这可以简单地扩展为处理默认值。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62873487

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档