2012-03-02 12 views
9

जीएनयू गेटोपेट, और कमांड लाइन टूल्स जो इसका उपयोग करते हैं, विकल्पों और तर्कों को इंटरलीव किए जाने की अनुमति देते हैं, जिन्हें अनुमति विकल्प के रूप में जाना जाता है (http://www.gnu.org/software/libc/manual/html_node/Using-Getopt.html#Using-Getopt देखें)। पर्ल गेटोपेट :: लांग मॉड्यूल भी इसका समर्थन करता है (qw (: config gnu_getopt) के साथ)। Argparse अनुमति विकल्प (या यहां तक ​​कि उल्लेख) का समर्थन नहीं करता प्रतीत होता है।क्या पाइथन का Argparse gnu getopt जैसे तर्क आदेश को अनुमति दे सकता है?

तर्क/ऑप्ट ऑर्डर से संबंधित कई SO प्रश्न हैं, लेकिन कोई भी इस प्रश्न का उत्तर नहीं दे रहा है: क्या तर्क प्राप्त करने के लिए तर्क प्राप्त करने के लिए तर्क दिया जा सकता है?

उपयोग के मामले जीएनयू तरह की तरह एक प्रोटोटाइप कमांड लाइन हस्ताक्षर है: जिसमें

sort [opts] [files] 

1) विकल्प और फ़ाइलों permuted हैं, और 2) फ़ाइल सूची शून्य या अधिक बहस हो सकती है।

उदाहरण के लिए:

import argparse 
p = argparse.ArgumentParser(); 
p.add_argument('files',nargs='*',default=['-']); 
p.add_argument('-z',action='store_true') 

p.parse_args(['-z','bar','foo']) # ok 
p.parse_args(['bar','foo','-z']) # ok 
p.parse_args(['bar','-z','foo']) # not okay 
usage: ipython [-h] [-z] [files [files ...]] 

मैं कोशिश की है:

  • p.parse_known_args - शिकायत नहीं है, लेकिन करता है वास्तव में या तो दूसरे स्थान पर रखना नहीं है और यह तर्क के बारे में भी मुंह नहीं करता जो अमान्य विकल्पों की तरह दिखता है (उदाहरण के लिए, - bogus या -b ऊपर)।
  • p.add_argument ('फ़ाइलें', nargs = argparse.REMAINDER) - विकल्प -z फ़ाइलों में शामिल किया जाता है, जब तक कि स्थितीय आर्ग
  • p.add_argument ('फ़ाइलें', nargs = '*', कार्रवाई से पहले = ' संलग्न ');

मैं ऊपर जीएनयू सॉर्ट प्रोटोटाइप के करीब कुछ कार्यान्वित करना चाहता हूं। मुझे ध्वज में दिलचस्पी नहीं है जिसे प्रत्येक फ़ाइल के लिए निर्दिष्ट किया जा सकता है (उदा। -f फ़ाइल 1 -f फ़ाइल 2)।

उत्तर

3

मैंने Argparse दस्तावेज़ में कुछ भी निश्चित नहीं देखा है जिसमें यह अनुमति दे सकती है या अनुमति नहीं दे सकती है। अपने स्वयं के अवलोकनों के आधार पर, जहां क्रमपरिवर्तन विफल हुआ, और निम्नलिखित दस्तावेज़ उद्धरण, मैं निष्कर्ष निकालने जा रहा हूं कि यह नहीं किया जा सकता है।

  1. वहां पहले से ही एक मॉड्यूल को स्पष्ट रूप से 'getopt' नाम दिया गया है:

    नोट getopt मॉड्यूल आदेश पंक्ति विकल्प जिसका एपीआई सी getopt() समारोह के उपयोगकर्ताओं के लिए परिचित होने की डिज़ाइन किया गया है के लिए एक पार्सर है। उपयोगकर्ता जो C getopt() फ़ंक्शन से अपरिचित हैं या को कम कोड लिखना चाहते हैं और बेहतर सहायता प्राप्त कर सकते हैं और त्रुटि संदेश पर argparse मॉड्यूल का उपयोग करके विचार करना चाहिए।

    इस समारोह getopt() तरह काम करता है, कि जीएनयू शैली स्कैनिंग मोड डिफ़ॉल्ट रूप से प्रयोग किया जाता है को छोड़कर:

  2. भी getopt दूसरे स्थान पर रखना नहीं करता है के लिए डिफ़ॉल्ट, वहाँ एक और अधिक स्पष्ट रूप से परिभाषित विधि gnu_getopt() नामित है। इसका अर्थ यह है कि विकल्प और गैर-विकल्प तर्क इंटरमीस्ड किया जा सकता है।

    ध्यान दें कि एक बराबर कमांड लाइन इंटरफेस कम कोड और अधिक सूचनात्मक के साथ उत्पादन किया जा सकता है:

  3. getopt डॉक्स में, argparse को उपरोक्त संदर्भ के निम्नलिखित शामिल किए जाने से आगे अतिशयोक्तिपूर्ण है argparse मॉड्यूल का उपयोग करके सहायता और त्रुटि संदेश:

Agai n, कुछ भी निश्चित नहीं है, लेकिन, मेरे लिए, गेटोपेट और Argparse के बीच एक बहुत तेज विभाजन खींचा जा रहा है दस्तावेज के साथ argparse पक्ष/समर्थन। 'का उपयोग getopt में अपने आप को दूसरे स्थान पर रखना जाओ, argparse

की "दूसरे स्थान पर रखना" परिभाषा से प्रेरित होकर साथ:

>>> args = 'file1 -z file2'.split() 
>>> args 
['file1', '-z', 'file2'] 
>>> opts, args = getopt.gnu_getopt(args, 'z') 
>>> opts 
[('-z', '')] 
>>> args 
['file1', 'file2'] 

संपादित करें 1:

यहाँ gnu_getop() का उपयोग कर एक उदाहरण है जो अपने -z [file [file]] परीक्षण satifies है 'पृष्ठ से जुड़े,

डिफ़ॉल्ट स्कैनिंग करते समय argv की सामग्री को अनुमति देना डिफ़ॉल्ट है तो कि आखिर में सभी गैर-विकल्प अंत में हैं।

parse_args() पर जाने से पहले तर्क स्ट्रिंग को अनुमति देने के बारे में कैसे?

import argparse 

p = argparse.ArgumentParser(); 
p.add_argument('files',nargs='*',default=['-']); 
p.add_argument('-z',action='store_true') 

अपनी खुद की जा रही है:

import re 

def permute(s, opts_ptn='-[abc]'): 
    """Returns a permuted form of arg string s using a regular expression.""" 
    opts = re.findall(opts_ptn, s) 
    args = re.sub(opts_ptn, '', s) 
    return '{} {}'.format(' '.join(opts), args).strip() 

>>> p.parse_args(permute('bar -z foo', '-[z]').split()) 
Namespace(files=['bar', 'foo'], z=True) 

इस्तेमाल getopt:

import getopt 

def permute(s, opts_ptn='abc'): 
    """Returns a permuted form of arg string s using `gnu_getop()'.""" 
    opts, args = getopt.gnu_getopt(s.split(), opts_ptn) 
    opts = ' '.join([''.join(x) for x in opts]) 
    args = ' '.join(args) 
    return '{} {}'.format(opts, args).strip() 

>>> p.parse_args(permute('bar -z foo', 'z').split()) 
Namespace(files=['bar', 'foo'], z=True) 
4

यहां एक त्वरित समाधान जो तर्क सूची डीकोड एक (विकल्प, स्थितीय तर्क) एक समय में जोड़ी है।

import argparse 

class ExtendAction(argparse.Action): 
    def __call__(self, parser, namespace, values, option_string=None): 
     items = getattr(namespace, self.dest, None) 
     if items is None: 
      items = [] 
     items.extend(values) 
     setattr(namespace, self.dest, items) 

parser = argparse.ArgumentParser() 
parser.add_argument('files', nargs='*', action=ExtendAction) 
parser.add_argument('-z', action='store_true') 
parser.add_argument('-v', action='count') 
parser.add_argument('args_tail', nargs=argparse.REMAINDER) 

def interleaved_parse(argv=None): 
    opts = parser.parse_args(argv) 
    optargs = opts.args_tail 
    while optargs: 
     opts = parser.parse_args(optargs, opts) 
     optargs = opts.args_tail 
    return opts 

print(interleaved_parse('-z bar foo'.split())) 
print(interleaved_parse('bar foo -z'.split())) 
print(interleaved_parse('bar -z foo'.split())) 
print(interleaved_parse('-v a -zv b -z c -vz d -v'.split())) 

आउटपुट:

Namespace(args_tail=[], files=['bar', 'foo'], v=None, z=True) 
Namespace(args_tail=[], files=['bar', 'foo'], v=None, z=True) 
Namespace(args_tail=[], files=['bar', 'foo'], v=None, z=True) 
Namespace(args_tail=[], files=['a', 'b', 'c', 'd'], v=4, z=True) 

नोट: (एक nargs='*' तर्क और args_tail तर्क के अलावा) अन्य गैर झंडा तर्क के साथ इस का उपयोग करने की कोशिश मत करो। पार्सर को parse_args के पिछले आमंत्रणों के बारे में पता नहीं चलेगा, इसलिए यह इन गैर-ध्वज तर्कों के लिए गलत मान संग्रहीत करेगा। एक कामकाज के रूप में, आप interleaved_parse का उपयोग करने के बाद मैन्युअल रूप से nargs='*' तर्क का विश्लेषण कर सकते हैं।

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