पाइथन ने आपसी अनन्य समूह को विकसित किया


88

मुझे क्या चाहिए:

pro [-a xxx | [-b yyy -c zzz]]

मैंने यह कोशिश की लेकिन काम नहीं करता। क्या कोई मेरी वहां मदद करेगा?

group= parser.add_argument_group('Model 2')
group_ex = group.add_mutually_exclusive_group()
group_ex.add_argument("-a", type=str, action = "store", default = "", help="test")
group_ex_2 = group_ex.add_argument_group("option 2")
group_ex_2.add_argument("-b", type=str, action = "store", default = "", help="test")
group_ex_2.add_argument("-c", type=str, action = "store", default = "", help="test")

धन्यवाद!



प्लगिंग, लेकिन मैं अपनी लाइब्रेरी जॉफ्री का उल्लेख करना चाहता था । यह करने के लिए कि आप यह प्रश्न क्या चाहते हैं, उदाहरण के लिए, बिना सबकोमांड (स्वीकृत उत्तर के रूप में) का उपयोग किए बिना या अपने आप को सब कुछ मान्य करें (जैसा कि दूसरे सबसे अधिक मत वाले जवाब में है)।
hallo

जवाबों:


109

add_mutually_exclusive_groupएक पूरे समूह को परस्पर अनन्य नहीं बनाता है। यह समूह के भीतर परस्पर अनन्य विकल्प बनाता है।

आप जो खोज रहे हैं, वह सब- वैंड है । प्रोग के बजाय [-a xxxx | [-b yyy -c zzz]], आपके पास होगा:

prog 
  command 1 
    -a: ...
  command 2
    -b: ...
    -c: ...

तर्कों के पहले सेट के साथ आह्वान करने के लिए:

prog command_1 -a xxxx

तर्क के दूसरे सेट के साथ आह्वान करने के लिए:

prog command_2 -b yyyy -c zzzz

आप उप कमांड तर्क को स्थिति के रूप में भी सेट कर सकते हैं।

prog command_1 xxxx

Git या svn की तरह:

git commit -am
git merge develop

काम करने का उदाहरण

# create the top-level parser
parser = argparse.ArgumentParser(prog='PROG')
parser.add_argument('--foo', action='store_true', help='help for foo arg.')
subparsers = parser.add_subparsers(help='help for subcommand')

# create the parser for the "command_1" command
parser_a = subparsers.add_parser('command_1', help='command_1 help')
parser_a.add_argument('a', type=str, help='help for bar, positional')

# create the parser for the "command_2" command
parser_b = subparsers.add_parser('command_2', help='help for command_2')
parser_b.add_argument('-b', type=str, help='help for b')
parser_b.add_argument('-c', type=str, action='store', default='', help='test')

झसे आज़माओ

>>> parser.print_help()
usage: PROG [-h] [--foo] {command_1,command_2} ...

positional arguments:
  {command_1,command_2}
                        help for subcommand
    command_1           command_1 help
    command_2           help for command_2

optional arguments:
  -h, --help            show this help message and exit
  --foo                 help for foo arg.
>>>

>>> parser.parse_args(['command_1', 'working'])
Namespace(a='working', foo=False)
>>> parser.parse_args(['command_1', 'wellness', '-b x'])
usage: PROG [-h] [--foo] {command_1,command_2} ...
PROG: error: unrecognized arguments: -b x

सौभाग्य।


मैंने उन्हें पहले ही एक तर्क समूह के तहत रखा है। मैं इस मामले में उप-कमान कैसे जोड़ सकता हूं? धन्यवाद!
सीन

1
नमूना कोड के साथ अद्यतन किया गया। आप समूहों का उपयोग नहीं करेंगे, लेकिन सबपर्सर्स।
जोनाथन

6
लेकिन ओपी ने जो पूछा, वह आप कैसे करेंगे? मेरे पास वर्तमान में उप-कमांडों का एक सेट है, लेकिन उन उप-कमांडों में से एक को चुनने की क्षमता की आवश्यकता है[[-a <val>] | [-b <val1> -c <val2>]]
code_dredd

2
यह सवाल का जवाब नहीं देता है क्योंकि यह आपको "नॉन" कमांड बनाने और ओपी के लिए जो कुछ भी मांगता है उसे हासिल करने की अनुमति नहीं देता है[-a xxx | [-b yyy -c zzz]]
द गॉडफादर

34

जबकि जोनाथन का जवाब जटिल विकल्पों के लिए पूरी तरह से ठीक है, एक बहुत ही सरल समाधान है जो सरल मामलों के लिए काम करेगा, जैसे 1 विकल्प में 2 अन्य विकल्प शामिल हैं जैसे

command [- a xxx | [ -b yyy | -c zzz ]] 

या मूल प्रश्न के अनुसार भी:

pro [-a xxx | [-b yyy -c zzz]]

यहाँ है कि मैं यह कैसे करेंगे:

parser = argparse.ArgumentParser()

# group 1 
parser.add_argument("-q", "--query", help="query", required=False)
parser.add_argument("-f", "--fields", help="field names", required=False)

# group 2 
parser.add_argument("-a", "--aggregation", help="aggregation",
                    required=False)

मैं यहाँ एक मोंगोडब को क्वेरी करने के लिए कमांड लाइन रैपर को दिए गए विकल्पों का उपयोग कर रहा हूँ। collectionउदाहरण के किसी भी विधि कॉल कर सकते हैं aggregateया विधि findवैकल्पिक तर्क के साथ queryऔर fields, इसलिए आप देख क्यों पहले दो तर्क संगत कर रहे हैं और पिछले एक नहीं है।

तो अब मैं parser.parse_args()इसे चलाता हूँ और इसकी सामग्री देखता हूँ:

args = parser().parse_args()

print args.aggregation
if args.aggregation and (args.query or args.fields):
    print "-a and -q|-f are mutually exclusive ..."
    sys.exit(2)

बेशक, यह छोटी सी हैक केवल सरल मामलों के लिए काम कर रही है और यदि आपके पास कई पारस्परिक अनन्य विकल्प और समूह हैं, तो सभी संभावित विकल्पों की जांच करना एक दुःस्वप्न बन जाएगा। उस मामले में आपको जोनाथन जैसे सुझाए गए समूहों में अपने विकल्पों को तोड़ना चाहिए।


5
मैं इस मामले के लिए इसे 'हैक' नहीं कहूंगा, क्योंकि यह अधिक पठनीय और प्रबंधनीय दोनों लगता है - इसे इंगित करने के लिए धन्यवाद!
ऋषि

13
उपयोग करने के लिए एक बेहतर तरीका होगा parser.error("-a and -q ...")। इस तरह पूर्ण उपयोग सहायता स्वचालित रूप से प्रिंट हो जाएगी।
WGH

कृपया ध्यान दें कि इस मामले में आप भी तरह के मामलों को मान्य करने की आवश्यकता होगी: (1) दोनों qऔर fपहले समूह में आवश्यक हैं उपयोगकर्ता, (2) या तो समूहों में से आवश्यक है। और यह "सरल" समाधान इतना सरल बनाता है कि कोई और अधिक नहीं। तो मैं सहमत हूँ कि यह दस्तकारी स्क्रिप्ट के लिए अधिक हैक है, लेकिन एक वास्तविक समाधान नहीं है
द गॉडफादर

4

एक अजगर पैच (विकास में) है जो आपको ऐसा करने की अनुमति देगा।
http://bugs.python.org/issue10984

विचार परस्पर अनन्य समूहों को ओवरलैप करने की अनुमति देना है। तो usageलग सकता है:

pro [-a xxx | -b yyy] [-a xxx | -c zzz]

इस तरह के दो समूह बना सकते हैं ताकि इस तरह के आसान भाग में परिवर्तन हो सके। usageएक कस्टम लिखने के लिए आवश्यक फ़ॉर्मेटिंग कोड को बदलना HelpFormatter

में argparse, कार्रवाई समूहों पार्स प्रभावित नहीं करते। वे सिर्फ एक helpस्वरूपण उपकरण हैं। में help, परस्पर अनन्य समूह केवल प्रभावित कर usageलाइन। जब पार्स करने, parserसंभावित टकराव का एक शब्दकोश (निर्माण करने के लिए पारस्परिक रूप से विशिष्ट समूहों का उपयोग करता है aके साथ नहीं हो सकता है bया c, bके साथ नहीं हो सकता है a, आदि), और फिर अगर एक संघर्ष उठता है एक त्रुटि को जन्म देती है।

उस बगैर पैच के, मुझे लगता है कि आपकी सबसे अच्छी पसंद अपने द्वारा निर्मित नामस्थान का परीक्षण करना है parse_args(जैसे कि यदि दोनों aऔर bउनके पास नॉन्डफॉल्ट मान हैं), और अपनी खुद की त्रुटि उठाएं। तुम भी पार्सर की अपनी त्रुटि तंत्र का उपयोग कर सकते हैं।

parser.error('custom error message')

1
पायथन मुद्दा: bugs.python.org/issue11588 आपको कस्टम अनन्य / समावेशी परीक्षण लिखने के तरीके तलाश रहा है।
हापुलज
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.