2010-08-11 18 views
11

वर्तमान में मेरा कोड इस तरह दिखता है। यह मुझे मेरे प्रोग्राम स्क्रिप्ट के कई मानकों को पार्स करने की अनुमति देता है। क्या कोई अलग तरीका है जो 'सर्वोत्तम प्रथाओं' के करीब है? मैंने वास्तव में argparse के आउटपुट का उपयोग करके कोड नहीं देखा है, केवल इसे कैसे सेट अप करें।कार्यों को कॉल करने के लिए argparse आउटपुट का उपयोग

def useArguments(): 
    x = 0 
    while x <= 5: 
     if x == 0:      
      if args.getweather != None: 
       getWeather(args.getweather) 
     if x == 1: 
      if args.post != None: 
       post(args.post) 
     if x == 2: 
      if args.custompost != None: 
       custompost(args.custompost) 
     if x == 3: 
      if args.list != None: 
       listAccounts(args.list) 
     if x == 4: 
      if args.add != None: 
       addAccount(args.add[0]) 
     if x == 5: 
      if args.edit != None: 
       editAccount(args.edit[0]) 
     x = x + 1  


if __name__ == '__main__': 

    updateConfig() 

    parser = argparse.ArgumentParser(description='Post Yahoo weather to Twitter.', epilog="Report any bugs to [email protected]", prog='Program') 

    parser.add_argument('-a', '--add', nargs=1, help='Add a new account. Use the desired account name as an argument.') 
    parser.add_argument('-e', '--edit', nargs=1, choices=accountListSTR[:-1], help='Edit an account. Use the desired account name as an argument.') 
    parser.add_argument('-g', '--getweather', nargs='*', choices=accountListSTR, help='Get weather and post here. Specify account(s) as argument. Use "all" for all accounts. If you specify multiple accounts, separate by a space NOT a comma.') 
    parser.add_argument('-p', '--post', nargs='*', choices=accountListSTR, help='Post weather to Twitter. Specify account(s) as argument. Use "all" for all accounts. If you specify multiple accounts, separate by a space NOT a comma.') 
    parser.add_argument('-c', '--custompost', nargs=2, help='Post a custom message. Specify an account then type the message. Make sure you use "" around the message. Use "all" for all accounts.') 
    parser.add_argument('-l', '--list', action='store_const', const='all', help='List all accounts.') 
    parser.add_argument('--version', action='version', version='%(prog)s 0.3.3') 

    args = parser.parse_args() 

    useArguments() 

उत्तर

11

आप द्वारा एक तर्क के लिए एक कस्टम action आपूर्ति कर सकता है, और मैं बोली:

एक वस्तु है कि कार्रवाई API लागू करता गुजर। यह करने का सबसे आसान तरीका argparse.Action, उचित __call__ विधि प्रदान करना है।

  1. पार्सर: ArgumentParser वस्तु जो इस कार्रवाई में शामिल है __call__ विधि चार मानकों को स्वीकार करना चाहिए।
  2. नामस्थान: नामस्थान वस्तु जो parse_args() द्वारा वापस की जाएगी। अधिकांश क्रियाएं इस ऑब्जेक्ट में एक विशेषता जोड़ती हैं।
  3. मूल्यों:। जुड़े कमांड लाइन आर्ग, किसी भी प्रकार के रूपांतरण के साथ लागू (टाइप-रूपांतरण add_argument() के प्रकार कीवर्ड तर्क के साथ निर्दिष्ट कर रहे हैं
  4. option_string:। विकल्प स्ट्रिंग है जो आह्वान करने के लिए इस्तेमाल किया गया था । इस कार्रवाई option_string तर्क वैकल्पिक है, और अगर कार्रवाई एक स्थितीय तर्क के साथ जुड़ा हुआ है अनुपस्थित हो जाएगा
+0

यह किस स्थिति में सबसे अच्छा तरीका होगा? मैं उस अतिरिक्त कोड के लिए उपयोग नहीं देख सकता। लेकिन फिर, मैंने मुश्किल से कक्षाओं का उपयोग किया ताकि मैं शायद कुछ खो रहा हूं। – avacariu

+1

@vlad, इसका उपयोग किसी फ़ंक्शन को स्वचालित रूप से एक फ़ंक्शन पर कॉल करने के लिए किया जा सकता है, जो आप कर रहे हैं वह सब आपके बॉयलरप्लेट - आपको केवल उचित उप-वर्गों के '__call__' विधियों को बनाना होगा 'argparse.Action' का। लेकिन यदि आप ऑब्जेक्ट उन्मुख प्रोग्रामिंग "प्राप्त नहीं करते हैं, तो यह ठीक है, आप इसे अपना रास्ता कर सकते हैं (हालांकि उस लूप और' यदि x ==' चेक किसी भी मामले में वास्तव में अनावश्यक हैं - बस एक के बाद चेक करें उचित कॉल द्वारा संभवतः अनुयायी कौन से तर्क मौजूद हैं, आपके द्वारा उपयोग किए जाने वाले अन्य बॉयलरप्लेट में कोई अतिरिक्त मूल्य नहीं है)। –

+0

इस उत्तर को स्वीकार किया क्योंकि यह मेरे प्रश्न का उत्तर देता है। मैं * यह सीखने के लिए कोशिश कर सकता हूं कि यह कैसे काम करता है; लेकिन इसमें वर्तमान में मेरा कोड कैसे काम करता है (विशेष रूप से वहां सूचीबद्ध फ़ंक्शंस) में कई बदलावों की आवश्यकता होगी। धन्यवाद! – avacariu

4
--version के अपवाद है, जो बहुत सामान्य एक विकल्प है के साथ

, कार्यों आपके द्वारा दिए गए बेहतर "subcommands" के रूप में इलाज कर रहे हैं।

myprog [--version] <command> [<command opts>...] 
:

मैं argparse बारीकियों से अनभिज्ञ हूं, जैसा कि मैंने अभी तक अजगर 2.7 कोशिश करने के लिए है, लेकिन आप एक उदाहरण के रूप svn आदेश पर एक नज़र ले सकता है, यहाँ कमांड लाइन के लिए कुछ स्यूडोकोड है

<command> कहाँ में:

add|edit|getweather|post|custompost|list 

और <command opts> कि आदेश के लिए विशिष्ट विकल्प हैं। optparse (जो समान है) का उपयोग करना, इसका मतलब यह होगा कि अपने आदेश args, में लौटा दिया जाएगा जब parse_args बुला आप इस तरह कुछ करने के लिए अनुमति देता है,:, जहां मैं डिबगिंग के लिए

opts, args = parser.parse_args() 
if opts.version: 
    ... 
else: 
    getattr("do_" + args[0])(*args[1:]) 

मुझे लगता है इस पद्धति विशेष रूप से उपयोगी कमांड लाइन से आंतरिक कार्यों तक पहुंच प्रदान करते हैं, और परीक्षण के लिए विभिन्न तर्क पारित करते हैं। अपने स्वयं के प्रोजेक्ट के लिए उपयुक्त कमांडर के चयन को समायोजित करें।

+0

'argparse' वास्तव में इस पैटर्न के लिए वास्तव में समर्थन प्रदान करता है। ('optparse' नहीं है।) मैं अभी भी पाइथन 2.6 पर फंस गया हूं इसलिए मुझे विनिर्देशों को ऑफहेड नहीं पता है, लेकिन उन्हें [दस्तावेज़ीकरण] में बताया गया है (http://docs.python.org/ पुस्तकालय/argparse.html # उप आदेशों)। –

+0

मेरे तर्कों से '--' को हटाने के बजाय ऐसा करने का क्या फायदा होगा। मुझे लगता है कि अंतिम उपयोगकर्ता के लिए यह वही दिख रहा है, है ना? मुझे लगता है कि ऐसा होने से उपयोगकर्ता के लिए और अधिक समझदारी होगी क्योंकि वे वास्तव में कस्टम पैरामीटर के साथ प्रोग्राम नहीं चला रहे हैं बल्कि इसे कुछ करने के लिए कह रहे हैं। – avacariu

+0

@ vlad003: यह सही है। कार्यक्रम के उपयोगकर्ता को एक और केवल "विकल्प" में से एक का चयन करना होगा, इसलिए वास्तव में वे आपके प्रोग्राम के लिए आदेश हैं। हालांकि, वे आदेश संभावित रूप से तर्क लेते हैं। प्रत्येक आदेश के लिए पृथक निष्पादन योग्य स्क्रिप्ट लिखना एक विकल्प है, प्रत्येक में अलग-अलग तर्क पार्सिंग करें, और कार्यान्वयन के लिए एक सामान्य कोड आधार पर कॉल करें। जैसे आपकी स्क्रिप्ट को बुलाया जा सकता है: myprog-list, myprog-add, आदि। हालांकि, मैं जोड़ सकता हूं, क्योंकि आप पाइथन-2.7 से Argparse का उपयोग कर रहे हैं, कि इसमें पहले से ही बहुत ही फैंसी तर्क हैंडलिंग हो सकती है। –

6

http://docs.python.org/library/argparse.html#sub-commands देखें:।

उप-आदेशों को संभालने का एक विशेष रूप से प्रभावी तरीका add_subparsers() विधि के उपयोग को set_defaults() पर कॉल के साथ जोड़ना है ताकि प्रत्येक उपपरक्षक जानता है कि कौन सा पायथन कार्य निष्पादित करना चाहिए।

संक्षेप में:

parser = argparse.ArgumentParser() 
subparsers = parser.add_subparsers() 

weather_parser = subparsers.add_parser('get-weather') 
weather_parser.add_argument('--bar') 
weather_parser.set_defaults(function=get_weather) # ! 

args = parser.parse_args(['get-weather', '--bar', 'quux']) 
print args.function(args) 

यहाँ हम आदेश get-weather के लिए एक subparser बना सकते हैं और इसे करने के लिए समारोह get_weather आवंटित।

ध्यान दें कि दस्तावेज़ीकरण कहता है कि कीवर्ड/विशेषता का नाम func है लेकिन यह निश्चित रूप से function Argparse 1.1 के रूप में है।

जिसके परिणामस्वरूप कोड थोड़ा भी अधिक शब्दों वाले है तो मैं एक छोटे पैकेज "argh" कि चीजें आसान बनाता है, जैसे प्रकाशित किया है:

parser = argparse.ArgumentParser() 
add_commands(parser, [get_weather]) 
print dispatch(parser, ['get-weather', '--bar', 'quux']) 

"अरे" कुछ कर सकते हैं, लेकिन मैं ढेर अतिप्रवाह जवाब दूँगा कि । :-)

+2

caffinatedmonkey द्वारा हालिया संपादन के बारे में ("मैं इस जवाब को ढेर नहीं कर दूंगा" → "मैं ढेर ओवरफ्लो जवाब दूंगा")। नया संस्करण ठीक लगता है लेकिन मुझे वास्तव में मतलब था कि जवाब फूला हुआ हो गया था, मैंने टेक्स्टरेरा में बहुत अधिक जानकारी भर ली थी। =) –

+0

क्या आप वाकई 'func'/'function' भाग अभी भी सत्य हैं? 'func' मेरे लिए ठीक काम करता है ... –

+0

न केवल उप-पारदर्शी दृष्टिकोण बदसूरत है, लेकिन ऐसा लगता है कि यह तर्क स्तर के निचले स्तर पर पार्सिंग का कार्य पास करता है - आपको या तो प्रत्येक' func 'में पास करने के लिए अलग-अलग फ़ंक्शन होना पड़ता है जो तब आपके "असली" कार्यों को कॉल करता है, या आपके वास्तविक कार्यों को सामान्य तर्कों को निर्देश देना होता है। मुझे लगता है कि पूर्व बड़े कार्यक्रमों के लिए ठीक है, लेकिन यह एक छोटे से कार्यक्रम में इतनी अतिरिक्त परतों को पेश करने के लिए हास्यास्पद लगता है।वही, सबपरर्स अब तक का सबसे अच्छा विकल्प प्रतीत होता है। –

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

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