2014-09-13 5 views
5

में बदल देता है मेरे पास एक पाइथन स्क्रिप्ट है जो दो उप-आदेश चलाती है जो एक ही विकल्प को स्वीकार करते हैं, --config। मैं एक तीसरा सब-कमांड बनाना चाहता हूं जो अनुक्रमिक रूप से पहले दो उप-सामग्रियों को एक साथ चला सकता है।subcommands में विकल्पों के लिए argparse संघर्ष समाधानकर्ता स्थिति तर्क को स्थितित्मक तर्क

Argparse का उपयोग करके, मैंने प्रत्येक सब-कमांड के साथ-साथ एक तृतीय उप-पाठक के लिए एक उपपरक्षक बनाया है, जिसका माता-पिता दो उप-आदेश हैं। बस स्पष्ट करने के लिए:

subcommand1 = subparsers.add_parser('subcommand1') 
subcommand1.add_argument('--config', help="The config") 

subcommand2 = subparsers.add_parser('subcommand2') 
subcommand2.add_argument('--config', help="The config") 

wrappercommand = subparsers.add_parser('wrappercommand', 
             parents=[subcommand1, subcommand2], 
             conflict_handler='resolve') 

जब मैं wrappercommand, या subcommand2 चलाता हूं तो सब कुछ काम करता है। हालांकि, आउटपुट के रूप में टूट जाता है subcommand1, इस के साथ:

$ run_command.py subcommand1 --config path_to_config.ini 

usage: run_command.py subcommand1 config 

optional arguments: 
    help     show this help message and exit 
    config    The config 

ऐसा लगता है कि argparse एक स्थितीय एक ("config") में कोई कीवर्ड आर्ग ("--config") कर दिया गया है। क्या यह अपेक्षित व्यवहार है जब विवाद विकल्पों को तर्कसंगत द्वारा हल किया जाता है?

+0

क्या आप पूर्ण पार्सिंग कोड पोस्ट कर सकते हैं? क्या तर्क 'सहायक' होना चाहिए? – Forge

+0

यह एक टाइपो है - यह 'help = "कॉन्फ़िगर" होना चाहिए। – hpaulj

उत्तर

3

मुझे लगता है कि आप इस संघर्ष हैंडलर को अनपेक्षित और अवांछित क्षेत्र में दबा रहे हैं। आम तौर पर parents स्टैंडअलोन पार्सर्स हैं जिनका उपयोग नहीं किया जाता है। वे Actions के लिए सिर्फ एक स्रोत हैं। और -h के संबंध में संघर्ष add_help=False के साथ संभाले जाते हैं।

पृष्ठभूमि के वैसे: डिफ़ॉल्ट conflict_handler (त्रुटि) के साथ आप जब wrappercommand subparser बनाने त्रुटि संदेश प्राप्त होता है:

argparse.ArgumentError: argument -h/--help: conflicting option string(s): -h, --help 

और कुछ add_help=False जोड़ने के बाद, आप अभी भी मिल चाहते हैं:

argparse.ArgumentError: argument --config: conflicting option string(s): --config 

resolve संघर्ष हैंडलर कुछ प्रकार के 'रिज़ॉल्यूशन' के साथ त्रुटि संदेशों को प्रतिस्थापित करता है। नीचे दी गई लिपि दर्शाती है कि क्या हो रहा है।

resolve हैंडलर ने subcommand1 कार्यों के लिए option_strings को हटा दिया, जबकि कार्यस्थलों को छोड़कर। असल में यह दोनों स्थिति में बदल जाता है। और चूंकि help में nargs=0 है, यह हमेशा चलता है। इसलिए, सहायता प्रदर्शित करता है।

_handle_conflict_resolve का इरादा पहला तर्क के साक्ष्य को हटाना है, इसलिए नया तर्क जोड़ा जा सकता है। यह ठीक काम करता है जब संघर्ष दो add_argument आदेशों द्वारा उसी विकल्प स्ट्रिंग के साथ बनाया जाता है। लेकिन यहां संघर्ष 2 माता-पिता से 'प्रतिलिपि' कार्यों द्वारा उत्पादित किया जाता है। लेकिन माता-पिता के कार्यों को संदर्भ द्वारा प्रतिलिपि बनाई जाती है, इसलिए 'बच्चे' में परिवर्तन 'माता-पिता' को प्रभावित करते हैं।

कुछ संभव समाधान:

  • wrappercommand सीधे करने के लिए तर्क जोड़ें। यह parents तंत्र सिर्फ माता-पिता से बच्चे को तर्क देता है। यह क्रमशः माता-पिता को 'रन' नहीं करता है।

  • अपने स्वयं के _handle_conflict_... फ़ंक्शन को सही तरीके से हल करने के लिए लिखें।

  • विवादों को हटा दें ताकि आप resolve हैंडलर का उपयोग किये बिना parents का उपयोग कर सकें।


मैं इस उदाहरण http://bugs.python.org/issue22401 साथ एक बग रिपोर्ट दायर की है:

parent1 = argparse.ArgumentParser(add_help=False) 
parent1.add_argument('--config') 
parent2 = argparse.ArgumentParser(add_help=False) 
parent2.add_argument('--config') 

parser = argparse.ArgumentParser(parents=[parent1,parent2], 
    conflict_handler='resolve') 

def foo(parser): 
    print [(id(a), a.dest, a.option_strings) for a in parser._actions] 

foo(parent1) 
foo(parent2) 
foo(parser) 

जो पैदा करता है:

[(3077384012L, 'config', [])] 
[(3076863628L, 'config', ['--config'])] 
[(3076864428L, 'help', ['-h', '--help']), (3076863628L, 'config', ['--config'])] 

नोट लापता parent1 के लिए option_strings, और मिलान id दूसरे के लिए 2. parent1 का उपयोग फिर से नहीं किया जा सकता है, या तो माता-पिता या पार्सर के रूप में।


argparse - Combining parent parser, subparsers and default values एक और मामले में जहां संदर्भ द्वारा नकल माता पिता की कार्रवाई जटिलताओं बनाता है (चूक को बदलने में) है।

+0

धन्यवाद, आपकी प्रतिक्रिया सभी बिंदुओं पर सही है। मैं 'माता-पिता' तंत्र का उपयोग किए बिना सीधे उपपरक्षक को विकल्प जोड़ने जा रहा हूं। – toothgrinder

संबंधित मुद्दे