簡體   English   中英

整齊地將位置參數作為args和可選參數傳遞為從argparse到函數的kwargs

[英]Neatly pass positional arguments as args and optional arguments as kwargs from argparse to a function

我想編寫一個Python腳本,通過argparse獲取一些必要的位置和一些可選的命令行參數:

  • 讓我們調用位置args abc和可選參數xyz
  • 在我的Python腳本中,我想將這些args傳遞給一個函數; 具體來說,我希望abc作為*args傳遞, xyz作為**kwargs傳遞,后者保留其名稱。
  • 我想用不同的函數和不同數量的位置和可選參數做很多次。 是否有一種整潔,靈活和/或pythonic的方式來做到這一點?

這是一些示例代碼:

import argparse

def parse():
    parser = argparse.ArgumentParser()
    parser.add_argument('a', help='1st arg')
    parser.add_argument('b', help='2nd arg')
    parser.add_argument('c', help='3rd arg')
    parser.add_argument('-x', '--x', help='1st kwarg')
    parser.add_argument('-y', '--y', help='2nd kwarg')
    parser.add_argument('-z', '--z', help='3rd kwarg')
    return parser.parse_args()

def func(*args, **kwargs):
    a, b, c = args
    print 'a=', a
    print 'b=', b
    print 'c=', c
    for k, v in kwargs.iteritems():
        print '%s=' % k, v

if __name__ == '__main__':

    all_args = parse()
    ### need to split all_args into args and kwargs here ###
    func(*args, **kwargs)

parse_args返回的Namespace將具有與每個參數對應的屬性。 位置參數和選項之間沒有區別,例如:

args
Namespace(a='1',b='one',x='foo', y=...)

根據文檔記錄,可以訪問以下內容:

args.a
args.x
etc.

Namespace也可以變成字典:

vars(args)
{'a'='1', 'b'='one', etc.}

您可以將字典作為**kwargs傳遞給函數。 這是標准的Python參數練習。

如果你想將一些參數作為*args傳遞,你必須自己將它們從Namespace或字典中分離出來。 argparse任何內容都不會為您做到這一點。

你可以寫一個像(未測試)的函數:

def split_args(args):
   vargs = vars(args)
   alist = ['a','b','c']
   args1 = []
   for a in alist:
        v = vargs.pop(a)
        args1.append(v)
   return args1, vars

或者更緊湊,將pop放入列表理解中:

In [702]: vargs = dict(a=1,b=3,c=4,x=5,y=3,z=3)
In [703]: [vargs.pop(a) for a in ['a','b','c']]
Out[703]: [1, 3, 4]
In [704]: vargs
Out[704]: {'y': 3, 'x': 5, 'z': 3}

In [705]: def foo(*args,**kwargs):
   .....:     print(args)
   .....:     print(kwargs)
   .....:     
In [706]: vargs = dict(a=1,b=3,c=4,x=5,y=3,z=3)
In [707]: foo(*[vargs.pop(a) for a in ['a','b','c']],**vargs)
(1, 3, 4)
{'x': 5, 'z': 3, 'y': 3}

使用自定義Action類的進一步想法

parser通過其option_strings屬性確定參數是optional positional的。 add_argument返回一個Action子類,它將具有以下屬性:

MyAction(option_strings=[], dest='baz', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)

這是一個positional因為option_strings是一個空列表。

MyAction(option_strings=['-m', '--mew'], dest='mew', nargs=None,...)

optional因為該列表不為空。

解析器使用option_stringsnargs匹配輸入字符串,然后將值傳遞給匹配Action__call__方法。 此方法定義如下:

def __call__(self, parser, namespace, values, option_string=None):
    setattr(namespace, self.dest, values)

這是默認的store操作。 這些值作為dest屬性放在Namespace中。

option_string參數是觸發此調用的字符串,類似於'-m'或'--mew',或者是positional None 定義的操作類型不使用它,但是用戶定義的Action類可以執行某些操作。

class MyAction(argparse._StoreAction):
   def __call__(self, parser, namespace, values, option_string=None):
       # store option_string along with values in the Namespace
       setattr(namespace, self.dest, [values,option_string])

或者你可以做一些特殊的positionals ,例如

       if option_string is None:
           # append values to a `star_args` attribute
           # rather than self.dest

通過這樣的操作,可以在解析后訪問positionals

args.star_args

解析器確實維護這樣的列表屬性。 parse_known_args返回的extras存儲在“_UNRECOGNIZED_ARGS_ATTR”屬性的Namespace中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM