2013-01-18 16 views
5

argparse (या कुछ और?) का उपयोग करके मैं प्रत्येक स्थितित्मक तर्क को डिफ़ॉल्ट मान के साथ वैकल्पिक तर्क प्राप्त करना चाहता हूं।प्रत्येक स्थितित्मक तर्क के लिए वैकल्पिक तर्क

तर्क के रूप में ऐसा होगा:

script.py arg1 arg2 -o 1 arg3 -o 2 arg4 arg5 

और मैं इसे कुछ प्रयोग करने योग्य, स्थितीय तर्कों की सूची और में भरा चूक के साथ वैकल्पिक तर्क की एक सूची की तरह में यह पार्स करने के लिए चाहता हूँ। जैसे अगर वैकल्पिक के लिए डिफ़ॉल्ट ऊपर के उदाहरण में 0:

positional = [arg1, arg2, arg3, arg4, arg5] 
optional = [0, 1, 2, 0, 0] 
दूसरे शब्दों में

, parser.add_argument('-o', action='append') जो मैं चाहता क्योंकि मैं स्थितीय तर्क खो देते हैं, प्रत्येक वैकल्पिक तर्क के लिए जुड़ा हुआ है नहीं है।

+0

क्या आप जानते हैं कि आपके पास कितने स्थितित्मक तर्क होंगे? – mgilson

+0

नहीं। मैं कितने परवाह किए बिना तर्कों पर लूप करना चाहता हूं। – bkanuka

उत्तर

3

यहाँ एक सरल हैक है कि मैं एक साथ रखा शुरू करने के लिए एक उचित जगह हो सकता है कि है:

import argparse 

class PositionalAction(argparse.Action): 
    def __call__(self,parser,namespace,values,option_string=None): 
     lst = getattr(namespace,self.dest) 
     lst.append(values) 
     parser.last_positional_values = lst 
     all_positional = getattr(namespace,'all_positional',[]) 
     all_positional.append(lst) 
     namespace.all_positional = all_positional 

class AssociateAction(argparse.Action): 
    def __call__(self,parser,namespace,values,option_string=None): 
     try: 
      parser.last_positional_values.append(values) 
     except AttributeError: 
      pass 

parser = argparse.ArgumentParser() 
parser.add_argument('-o',action=AssociateAction,dest=argparse.SUPPRESS) 
junk,unknown = parser.parse_known_args() 

for i,_ in enumerate(unknown): 
    parser.add_argument('arg%d'%i,action=PositionalAction,default=[]) 

print parser.parse_args() 

और यहाँ यह कार्रवाई में है:

temp $ python test1.py foo -o 1 bar -o 2 baz qux -o 4 
Namespace(all_positional=[['foo', '1'], ['bar', '2'], ['baz'], ['qux', '4']], arg0=['foo', '1'], arg1=['bar', '2'], arg2=['baz'], arg3=['qux', '4']) 

यह समस्या कुछ चुनौतियों है। सबसे पहले, आप स्थितित्मक तर्कों की मनमानी संख्या को स्वीकार करना चाहते हैं - Argparse को यह पसंद नहीं है। Argparse आगे की जानना चाहता है कि क्या उम्मीद करनी है। समाधान एक पार्सर बनाने और कमांडलाइन को पार्स करना है, लेकिन केवल तर्कसंगत तर्कों को पार्स करने के लिए Argparse को बताने के लिए (इस मामले में, गैर-स्थिति -o तर्क सभी चुपचाप पार्स किए जाते हैं लेकिन "स्थितित्मक" तर्कों को पार्स नहीं किया जाता है।) । parse_known_args इसके लिए बिल्कुल सही है क्योंकि यह फॉर्म (namespace_of_parsed_stuff, uknown_args) में एक टुपल देता है। तो अब हम अज्ञात तर्कों को जानते हैं - हमें प्रत्येक को पार्स_र्ग खुश करने के लिए पार्सर को एक स्थितित्मक तर्क जोड़ने की आवश्यकता है।

अब, वास्तव में कस्टम क्रियाएं क्या कर रही हैं? जब एक स्थितित्मक तर्क पाया जाता है (दूसरे पास पर), हम डिफ़ॉल्ट (जो एक सूची है) प्राप्त करते हैं और उस सूची में मान जोड़ते हैं (इसके बाद मैं इसे "मान" सूची कहूंगा)। इसके बाद हम "मूल्य" सूची के संदर्भ में पार्सर संशोधित करते हैं। हमें नामस्थान से "all_positional" सूची भी मिलती है। अगर इसमें वह विशेषता नहीं है, तो हमें बस एक खाली सूची मिल जाएगी। हम "all_positional" सूची में "मान" सूची जोड़ते हैं और इसे नामस्थान पर वापस डाल देते हैं।

अब, जब हम एक -o झंडा मारा, हम पार्सर में "मूल्य" सूची प्राप्त करने के देखने के लिए और हम चाहते हैं कि सूची में अतिरिक्त मूल्य जोड़ने। हम पार्सर को छूए बिना भी वही काम कर सकते थे ... (हम namespace.all_positional[-1] देख सकते हैं - यह parser.last_positional_values जैसा ही सूची है)।

+0

आपके द्वारा उत्पादित यह जादू ऐसा लगता है जो मैं चाहता हूं (या पर्याप्त बंद करें), लेकिन मुझे यह समझने में थोड़ी देर लग जाएगी कि आपने क्या किया है। भले ही, धन्यवाद! – bkanuka

+0

मैं उम्मीद करता हूं कि यह क्या हो रहा है इसके बारे में कुछ टिप्पणियां जोड़कर इसे और अधिक समझने में मदद मिलेगी। – mgilson

+0

चिंता न करें, स्पष्टता की कमी की तुलना में गलतफहमी निश्चित रूप से विशेषज्ञता की कमी के साथ और अधिक करने के लिए है। – bkanuka

-1

उपयोग optparse, यह शक्तिशाली है, तो एक छोटा सा जटिल:

op = optparse.OptionParser(usage=usage) 

op.add_option('-c','--cmd',dest='cmd',help="""Command to run. Mutually exclusive with -s. You can use string ${ADDR} to have it replaced with specified host address in the command. """) 

op.add_option('-s','--script',dest='script',help="""Script file to run remotely. Mutually exclusive with -c. A script can have its own arguments; specify the whole command in doublequotes, like "script -arg arg".""") 

op.add_option('-l','--replicate-owner',dest='replicateowner',action="store_true",help="""Replicate (symbolic) owner and (symbolic) group of the file on the remote host, if possible. If remote account with username the same as local account does not exist on remote host, this will silently fail.""") 

# parse cmdline options 
(opts, args) = op.parse_args() 

opts आप आर्ग और आर्ग आप स्थितीय आर्ग हो जाता है नामित हो जाता है।

आप स्थितीय तर्क मान लेने या सही या गलत और अधिक IIRC की स्थापना हो सकती है।

+2

यह विशिष्ट प्रश्न का उत्तर नहीं देता है। पोस्टर सामान्य रूप से {opt, arg} पार्स का उपयोग करने के बारे में जागरूक प्रतीत होता है। – chepner

0

बस sys.argv के माध्यम से बसने के बारे में कैसे। आपको अतिरिक्त सुविधाओं की आवश्यकता नहीं है जो Argparse ऑफ़र प्रदान करता है। उदाहरण के लिए:

argv='script.py arg1 arg2 -o 1 arg3 -o 2 arg4 arg5'.split() 
pos=[] 
opt=[] 
i=1 
while i<len(argv): 
    a=argv[i] 
    if a[:2]!='-o': 
     pos.append(a) 
     opt.append(0) 
    else: 
     i += 1 
     opt[-1]=argv[i] 
    i += 1 
संबंधित मुद्दे