2012-08-28 20 views
5

मैं एक argparse.ArgumentParser वस्तु से वैश्विक विकल्पों का उपयोग करने ओवरराइड/एक उप आदेश के लिए चूक मान बढ़ाने के लिए सक्षम होने के लिए चाहते हैं के माध्यम से उप आदेश चूक बढ़ाने।argparse वैश्विक विकल्प

एक उदाहरण होगा हो कि दिखाया गया है मदद वैश्विक अद्यतन, यानी, निम्नलिखित खिलौना उदाहरण के लिए दर्शाता है:

import argparse 
import os 
import sys 

# Global parser and options. 
parser = argparse.ArgumentParser(
    formatter_class=argparse.ArgumentDefaultsHelpFormatter) 

parser.add_argument("--user", 
        dest="user", 
        default=os.environ.get("USER"), 
        help="Override the setting of the $USER variable.") 

# Sub-command parser and options. 
subparsers = parser.add_subparsers() 

command = subparsers.add_parser(
    "command", 
    formatter_class=argparse.ArgumentDefaultsHelpFormatter) 

command.add_argument("--config", 
        dest="config", 
        default="~%s/config" % os.environ.get("USER"), 
        help="The config file.") 

options = parser.parse_args() 

आदर्श रूप में जब मैं मिलेगा जब मैं मदद के मोड में इस चलाने के लिए,

> python example.py --user thing command --help 
usage: example.py command [-h] [--config CONFIG] 

optional arguments: 
    -h, --help  show this help message and exit 
    --config CONFIG The config file. (default: ~thing/config) 

यानी, कॉन्फ़िगर फ़ाइल पथ उपयोगकर्ता विशिष्ट (चीज़) है। मुझे एहसास है कि मैं "~%(user)s/config" होने के लिए डिफ़ॉल्ट कॉन्फ़िगरेशन को बदल सकता हूं और फिर विकल्प नामस्थान के साथ रन-टाइम पर इसे हल कर सकता हूं, हालांकि मैं सहायता को और अधिक स्पष्ट होना चाहता हूं।

मैं, इकट्ठा कोई वैकल्पिक समाधान, एक बार तर्क पार्स करने के लिए वैश्विक विकल्प प्राप्त करने के लिए प्रयास करने के लिए अर्थात होगा

if "--help" in sys.argv: 

    # Parse the command minus the help to obtain the global options. 
    args = sys.argv[1:] 
    args.remove("--help") 

    # Update the defaults with the global options. 
    options = parser.parse_args(args) 
    command.set_defaults(config="~%s/config" % options.user) 

    # Re-parse the options. 
    parser.parse_args() 

हालांकि यह कुछ हद तक hacky लगता है। क्या कोई बेहतर दृष्टिकोण/समाधान है?

उत्तर

4

वैश्विक विकल्पों को परिभाषित करने के बाद, लेकिन उप-सामग्रियों को परिभाषित करने से पहले, --user का मान पता लगाने के लिए parse_known_args पर कॉल करें। फिर, subparser आदेशों को परिभाषित करने, कमांड लाइन पर सभी विकल्प पार्स करने के लिए parse_args बुला --user के मूल्य का उपयोग कर --config के डिफ़ॉल्ट परिभाषित करने के लिए, से पहले खत्म।

यह आपके विकल्प से थोड़ा अलग है, लेकिन यह argparse वस्तु के अंदर सभी कमांड लाइन प्रसंस्करण रहता है।

import os 
import argparse 

# Global preparser and options. 
preparser = argparse.ArgumentParser(add_help=False) 
preparser.add_argument("--user", dest="user", default=os.environ.get("USER")) 

# ****** NEW ******* 
options, _ = preparser.parse_known_args() # Ignore what we haven't defined yet 
user = options.user      # Use this to define the default of --config 

parser = argparse.ArgumentParser(parents=[ preparser ], add_help=True, 
        formatter_class=argparse.ArgumentDefaultsHelpFormatter) 

# Sub-command parser and options. 
subparsers = parser.add_subparsers() 

command = subparsers.add_parser("command") 

# ****** MODIFIED ******* 
command.add_argument("--config", dest="config", default="~%s/config" % (user,)) 

options = parser.parse_args() 
+0

प्रतिक्रिया के लिए धन्यवाद। यह दृष्टिकोण निश्चित रूप से मेरे दृष्टिकोण से अधिक स्वच्छ/सरल है और एक दृष्टिकोण के समान मैं बिना किसी तर्क के कोशिश कर रहा था, यानी तर्कों को दो बार विश्लेषण करना। मैं यह देखने के लिए कोड देख सकता हूं कि मैं विकल्प के साथ वापस लौटने के लिए parse_known_args() कैसे प्राप्त कर सकता हूं (बाहर निकलने के विपरीत) जब "--help" तर्क मेरे उदाहरण के अनुसार इसे हटाने के बजाय प्रदान किया जाता है। – John

+0

ओह, मैं इसके बारे में भूल गया। आप 'SystemExit' अपवाद को पकड़ सकते हैं कि 'parse_known_args()' फेंक देगा जब यह' ArgumentParser.exit' (जो 'sys.exit' के आसपास अपेक्षाकृत पतला रैपर होता है) फेंक देगा। – chepner

+0

अरे, हाँ मैंने कोशिश की है, हालांकि कोशिश/छोड़कर समस्या यह है कि विकल्प अपरिभाषित हैं। – John

0

यहाँ एक समाधान है कि हेल्पलाइन सीधे संशोधित करता है, क्रम में है (मैं अपने कोड एक छोटे से सिर्फ इस उत्तर के लिए यह छोटा करने के लिए। कांट छांट)। यह os.environ या कुछ अन्य वैश्विक भी संशोधित कर सकता है, लेकिन मैं इसे सरल रखूंगा। कुंजी एक चर के लिए add_argument('--config'...) द्वारा बनाई गई क्रिया को असाइन कर रही है। help उस चर का एक विशेषता है। आप इसे संशोधित करने के लिए स्वतंत्र हैं।

class FooAction(argparse.Action): 
    def __call__(self, parser, namespace, values, option_string=None): 
     config.help = 'new user (%s)'% values 
     setattr(namespace, self.dest, values) 

parser = argparse.ArgumentParser() 
parser.add_argument('--user',action=FooAction) 
sub = parser.add_subparsers() 
cmd = sub.add_parser('cmd') 
config = cmd.add_argument('--config',help='initial help') 
config.help = 'default help' # alt way of setting 'help' 
# print config # to see other attributes of the config action 
args = parser.parse_args() 
print args 

सिर्फ cmd -h के साथ आमंत्रण हम default help

$ python stack12167228.py cmd -h 
usage: stack12167228.py cmd [-h] [--config CONFIG] 

optional arguments: 
    -h, --help  show this help message and exit 
    --config CONFIG default help 

--user xxx cmd -h के साथ आमंत्रण मिलता है, मदद अनुकूलित है

$ python stack12167228.py --user xxx cmd -h 
usage: stack12167228.py cmd [-h] [--config CONFIG] 

optional arguments: 
    -h, --help  show this help message and exit 
    --config CONFIG new user (xxx) 
संबंधित मुद्दे