Sử dụng một hành động tùy chỉnh:
import argparse
foo_default=None
class BarAction(argparse.Action):
def __call__(self,parser,namespace,values,option_string=None):
didfoo=getattr(namespace,'foo',foo_default)
if(didfoo == foo_default):
parser.error("foo before bar!")
else:
setattr(namespace,self.dest,values)
parser=argparse.ArgumentParser()
parser.add_argument('--foo',default=foo_default)
parser.add_argument('--bar',action=BarAction,help="Only use this if --foo is set")
#testing.
print parser.parse_args('--foo baz'.split())
print parser.parse_args('--foo baz --bar cat'.split())
print parser.parse_args('--bar dog'.split())
này thậm chí có thể được thực hiện trong dễ dàng hơn một chút để duy trì cách nếu bạn OK với dựa vào một số hành vi không có giấy tờ của argparse:
import argparse
parser=argparse.ArgumentParser()
first_action=parser.add_argument('--foo',dest='cat',default=None)
class BarAction(argparse.Action):
def __call__(self,parser,namespace,values,option_string=None):
didfoo=getattr(namespace,first_action.dest,first_action.default)
if(didfoo == first_action.default):
parser.error("foo before bar!")
else:
setattr(namespace,self.dest,values)
parser.add_argument('--bar',action=BarAction,
help="Only use this if --foo is set")
#testing.
print parser.parse_args('--foo baz'.split())
print parser.parse_args('--foo baz --bar cat'.split())
print parser.parse_args('--bar dog'.split())
Trong ví dụ này, chúng tôi nhận được mặc định cho foo
và đích đến của nó từ đối tượng hành động được trả về bởi add_argument
(giá trị trả lại của add_argument không được ghi lại ở bất kỳ nơi nào tôi có thể tìm thấy). Điều này vẫn còn một chút mong manh (Nếu bạn muốn chỉ định một từ khóa type=
cho đối số --foo
chẳng hạn).
Cuối cùng, bạn có thể kiểm tra sys.argv
trước khi phân tích cú pháp.
import sys
if ("--parameter2" in sys.argv) and ("--parameter1" not in sys.argv):
parser.error("parameter1 must be given if parameter2 is given")
này được một chút khó khăn hơn nếu --parameter1
cũng có thể được kích hoạt bởi --p1
, nhưng bạn sẽ có được ý tưởng. Sau đó, bạn có thể sử dụng
if (set(sys.argv).intersection(('--p2',...)) and
not set(sys.argv).intersection(('--p1',...)))
Lợi thế ở đây là không yêu cầu bất kỳ thứ tự cụ thể nào. (--p2
không cần theo dõi --p1
trên dòng lệnh). Và, như trước đây, bạn có thể nhận được danh sách các chuỗi lệnh sẽ kích hoạt hành động cụ thể của bạn thông qua thuộc tính option_strings
được trả về bởi parser.add_argument(...)
. ví dụ.
import argparse
import sys
parser=argparse.ArgumentParser()
action1=parser.add_argument('--foo')
action2=parser.add_argument('--bar',
help="Only use this if --foo is set")
argv=set(sys.argv)
if ((argv & set(action2.option_strings)) and
not (argv & set(action1.option_strings))):
#^ set intersection
parser.error(' or '.join(action1.option_strings)+
' must be given with '+
' or '.join(action2.option_strings))
gì làm bạn muốn xảy ra nếu 'myScript.py --parameter2 value2 --parameter1 value1'? Đây là một trường hợp rất khó giải quyết nếu bạn muốn nó vượt qua. – mgilson
http://bugs.python.org/issue11588 là một yêu cầu về lỗi đối với tính năng 'mutually_inclusive_group'. Điều đó sẽ không hoàn toàn hoạt động trong trường hợp này, vì '--parameter1' có thể xảy ra mà không có' --parameter2'. Đóng góp cho vấn đề đó nếu bạn có ý tưởng về cách thức này hoặc các ràng buộc liên quan có thể được thực hiện. – hpaulj