यहाँ एक सरल हैक है कि मैं एक साथ रखा शुरू करने के लिए एक उचित जगह हो सकता है कि है:
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
जैसा ही सूची है)।
क्या आप जानते हैं कि आपके पास कितने स्थितित्मक तर्क होंगे? – mgilson
नहीं। मैं कितने परवाह किए बिना तर्कों पर लूप करना चाहता हूं। – bkanuka