2011-11-23 11 views
12

मान लें कि मेरे पास एक स्क्रिप्ट है जो फ़ाइल पर कुछ काम करती है। यह कमांड लाइन पर इस फ़ाइल का नाम लेता है, लेकिन अगर यह प्रदान नहीं किया जाता है, तो यह ज्ञात फ़ाइल नाम (content.txt, कहें) पर डिफ़ॉल्ट होता है।Argparse के साथ डिफ़ॉल्ट फ़ाइल नाम निर्दिष्ट करना, लेकिन उन्हें --help पर नहीं खोल रहा है?

parser = argparse.ArgumentParser(description='my illustrative example') 
parser.add_argument('--content', metavar='file', 
        default='content.txt', type=argparse.FileType('r'), 
        help='file to process (defaults to content.txt)') 
args = parser.parse_args() 
# do some work on args.content, which is a file-like object 

यह महान काम करता है: अजगर के argparse के साथ, मैं निम्नलिखित का उपयोग करें। एकमात्र समस्या यह है कि यदि मैं python myscript --help चलाता हूं, तो मुझे ArgumentError मिलता है यदि फ़ाइल वहां नहीं है (जो मुझे लगता है), और सहायता टेक्स्ट नहीं दिखाया गया है। अगर मैं सिर्फ --help चाहता हूं तो मैं फ़ाइल खोलने की कोशिश नहीं करता। क्या इसे करने का कोई तरीका है? मुझे पता है कि मैं तर्क को एक स्ट्रिंग बना सकता हूं और बाद में फ़ाइल खोलने का ख्याल रखता हूं (और मैं ऐसा कर रहा हूं), लेकिन argparse इसकी देखभाल करना सुविधाजनक होगा।

+0

ठीक है, ऐसा लगता है कि तुम यहाँ एक निर्णय करने के लिए होगा। आप या तो डिफ़ॉल्ट फ़ाइल उपलब्ध कर सकते हैं (इसके आधार पर 'डिफ़ॉल्ट' होने के कारण) या फ़ाइल को स्वयं खोलें, जैसा आपने स्वयं सुझाया है। वैकल्पिक रूप से, ऐसा लगता है कि आप डिफ़ॉल्ट रूप से stdin का उपयोग कर सकते हैं, हालांकि आप एक डिफ़ॉल्ट फ़ाइल नाम निर्दिष्ट करने में सक्षम नहीं होंगे, जो कि यदि आप उस फ़ाइल को पॉप्युलेट नहीं करना चाहते हैं तो यह एक बुरा विकल्प नहीं हो सकता है। –

उत्तर

9

argparse कोड को देखते हुए, मैं देख रहा हूँ:

  • ArgumentParser.parse_args कॉल parse_known_args और यकीन है कि वहाँ किसी भी लंबित तर्क पार्स किया जा सकता है कि बनाता है।
  • ArgumentParser.parse_known_args सेट मूलभूत मूल्यों और इसलिए कॉल ArgumentParser._parse_known_args

, वैकल्पिक हल सीधे -h का पता लगाने और उसके बाद, हमेशा की तरह ArgumentParser.parse_args उपयोग करने के लिए ArgumentParser._parse_known_args उपयोग करने के लिए किया जाएगा।

import sys, argparse 
parser = argparse.ArgumentParser(description='my illustrative example', argument_default=argparse.SUPPRESS) 
parser.add_argument('--content', metavar='file', 
        default='content.txt', type=argparse.FileType('r'), 
        help='file to process (defaults to content.txt)') 
parser._parse_known_args(sys.argv[1:], argparse.Namespace()) 
args = parser.parse_args() 

ध्यान दें कि ArgumentParser._parse_known_args मानकों की एक जोड़ी की जरूरत है: आदेश पंक्ति और नाम स्थान से तर्क।

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

+0

ऐसा लगता है कि वास्तव में इसका कोई अच्छा समाधान नहीं है, लेकिन यह एक-एक-एक स्क्रिप्ट के लिए करेगा। धन्यवाद! –

1

शायद आप add_argument कॉल कि जाँच करता है, तो फ़ाइल मौजूद है, और एक फ़ाइल हैंडल लौटाता है यदि यह करता है और None (या कुछ और) अन्यथा में अपने स्वयं के type या action निर्धारित कर सकते हैं।

यह आपको अपने आप को कुछ कोड लिखने की आवश्यकता होगी, लेकिन यदि डिफ़ॉल्ट मान हमेशा उपयोग नहीं किया जा सकता है तो आपको शायद जल्दी या बाद में कुछ जांच करनी होगी। मैनी डी की तरह तर्क है कि आप अपने डिफ़ॉल्ट मान पर पुनर्विचार करना चाहेंगे।

12

आप argparse.FileType उपवर्ग सकता है:

import argparse 
import warnings 

class ForgivingFileType(argparse.FileType): 
    def __call__(self, string): 
     try: 
      super(ForgivingFileType,self).__call__(string) 
     except IOError as err: 
      warnings.warn(err) 

parser = argparse.ArgumentParser(description='my illustrative example') 
parser.add_argument('--content', metavar='file', 
        default='content.txt', type=ForgivingFileType('r'), 
        help='file to process (defaults to content.txt)') 
args = parser.parse_args() 

यह काम करता है ArgumentParser._parse_known_args की तरह निजी तरीकों स्पर्श किए बिना। डिफ़ॉल्ट के रूप में

2

stdin उपयोग:

parser.add_argument('file', default='-', nargs='?', type=argparse.FileType('r')) 
संबंधित मुद्दे