https://docs.python.org/3/library/argparse.html#the-namespace-object
Lớp này là cố tình đơn giản, chỉ là một lớp con đối tượng với một chuỗi đại diện có thể đọc được. Nếu bạn muốn có cái nhìn dict giống như các thuộc tính, bạn có thể sử dụng các tiêu chuẩn thành ngữ Python, vars():
>>>
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> args = parser.parse_args(['--foo', 'BAR'])
>>> vars(args)
{'foo': 'BAR'}
Lưu ý rằng một trong những tiến bộ lớn, hoặc thay đổi ít nhất, từ optparse
đến argparse
là các đối số vị trí, chẳng hạn như đối số của bạn, được xử lý giống như tùy chọn. Cả hai đều xuất hiện trong đối tượng args
Namespace
. Trong optparse
, các vị trí chỉ là phần còn lại từ việc phân tích cú pháp các tùy chọn được xác định. Bạn có thể nhận được tác dụng tương tự trong argparse
bởi omiting đối số của bạn và sử dụng parse_known_args
:
parser = argparse.ArgumentParser()
args, extras = parser.parse_known_args()
args
bây giờ là một không gian tên, và extras
một danh sách. Sau đó bạn có thể gọi hàm của bạn như:
myfoo(*extras, **vars(args))
Ví dụ:
In [994]: import argparse
In [995]: def foo(*args, **kwargs):
.....: print(args)
.....: print(kwargs)
.....:
In [996]: parser=argparse.ArgumentParser()
In [997]: parser.add_argument('-f','--foo')
Out[997]: _StoreAction(option_strings=['-f', '--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
In [998]: args,extras = parser.parse_known_args(['-f','foobar','arg1','arg2'])
In [999]: args
Out[999]: Namespace(foo='foobar')
In [1000]: extras
Out[1000]: ['arg1', 'arg2']
In [1001]: foo(*extras, **vars(args))
('arg1', 'arg2')
{'foo': 'foobar'}
Cùng argparse
đoạn cho thấy bạn có thể định nghĩa lớp Namespace
của riêng bạn.Nó sẽ không khó để xác định một trong đó hoạt động như một từ điển (để sử dụng như **args
) và như không gian tên. Tất cả argparse
yêu cầu là nó hoạt động với getattr
và setattr
.
In [1002]: getattr(args,'foo')
Out[1002]: 'foobar'
In [1004]: setattr(args,'bar','ugg')
In [1005]: args
Out[1005]: Namespace(bar='ugg', foo='foobar')
một tính năng Python chuẩn cho phép tôi vượt qua vars(args)
như một tuple:
In [1013]: foo(*vars(args).items())
(('foo', 'foobar'), ('bar', 'ugg'))
{}
Đối với một câu trả lời tương tự từ cuối tháng Giêng: https://stackoverflow.com/a/34932478/901925
Neatly pass positional arguments as args and optional arguments as kwargs from argpase to a function
Ở đó tôi đưa ra ý tưởng về cách để tách 'vị trí' khỏi 'tùy chọn' sau khi phân tích cú pháp.
Dưới đây là một lớp không gian tên tùy chỉnh bao gồm, trong API của nó, một phương tiện để trở về chính nó như là một cuốn từ điển:
In [1014]: class MyNameSpace(argparse.Namespace):
......: def asdict(self):
......: return vars(self)
......:
In [1015]: args = parser.parse_args(['-f','foobar'], namespace=MyNameSpace())
In [1016]: args
Out[1016]: MyNameSpace(foo='foobar')
In [1017]: foo(**args.asdict())
()
{'foo': 'foobar'}
ý tưởng khác - sử dụng một trong những nhiều nargs
(2, '*', '+') cho đối số vị trí. Sau đó, bạn chỉ có một tên để nhập khi chuyển nó vào hàm của bạn.
parser.add_argument('pos',nargs='+')
args = ...
args.pos # a list, possibly empty
foo(*args.pos, **vars(args))
Tôi không muốn đóng gói arg vào bộ túp cho chức năng chính của mình nếu tôi nhập/gọi nó từ gói khác. Tôi rất thích lời gọi phương thức 'parse_arguments'. Tôi thực sự yêu điều đó. –