कमांड लाइन के तर्क कैसे पढ़ें / प्रोसेस करें?


622

5
Docopt का उपयोग करें (देखें @ ralbatross का जवाब stackoverflow.com/a/14790373/116891 पर )। मैं हर दूसरे तरीके की कोशिश की है और, वास्तव में, docopt केवल एक ही है जिसका मैं आगे बढ़ने में उपयोग करूंगा।
पैट

2
मुझे नहीं लगता कि कोई एक सबसे अच्छा तरीका है। argparse मानक और विशेषता है। docopt बहुत सुरुचिपूर्ण है लेकिन मानक पुस्तकालय में नहीं है। बहुत आसान हल्के उपयोग के लिए आप फंक्शन डिफॉल्ट वैल्यू को संभाल सकते हैं जो आपके लिए कॉमन लाइन लॉजिक डिफॉल्ट को हैंडल करता है
साइमन हिब्स

जवाबों:


455

मानक पुस्तकालय में विहित समाधान argparse( डॉक्स ) है:

यहाँ एक उदाहरण है:

from argparse import ArgumentParser

parser = ArgumentParser()
parser.add_argument("-f", "--file", dest="filename",
                    help="write report to FILE", metavar="FILE")
parser.add_argument("-q", "--quiet",
                    action="store_false", dest="verbose", default=True,
                    help="don't print status messages to stdout")

args = parser.parse_args()

argparse समर्थन (अन्य बातों के अलावा):

  • किसी भी क्रम में कई विकल्प।
  • छोटे और लंबे विकल्प।
  • डिफ़ॉल्ट मान।
  • उपयोग सहायता संदेश का निर्माण।

27
हां, ये सबसे अच्छे हैं। चूंकि वे मानक पुस्तकालय का हिस्सा हैं, आप यह सुनिश्चित कर सकते हैं कि वे उपलब्ध रहेंगे और उनका उपयोग करना आसान है। विशेष रूप से ऑप्टपर्स शक्तिशाली और आसान है।
बैरी वार्क

4
ऑप्टपर्स सबसे अच्छा में से एक है; getopt पुराना है और वास्तव में पदावनत माना जाना चाहिए।
जैमफिन्च

12
इस बिंदु पर (12/2011), ऑर्गपर्स को अब ऑप्टपर्स से बेहतर विकल्प माना जाता है, सही है?
oob

54
पाइथन डॉक्यूमेंटेशन से ऑप्टपर्स के बजाय एर्गपर्स के उपयोग का सुझाव मिलता है।
EarthmeLon

7
जब optparseसे पदावनत किया गया है, प्रश्न पूछने वाला अब स्टैक ओवरफ्लो पर एक सदस्य नहीं है, और यह एक अत्यधिक दृश्यमान प्रश्न पर स्वीकृत उत्तर है - कृपया argparseइसके बजाय stdlib का उपयोग करने के लिए अपने उदाहरण कोड को पूरी तरह से फिर से लिखने पर विचार करें ।
विम

548
import sys

print("\n".join(sys.argv))

sys.argv एक सूची है जिसमें कमांड लाइन पर स्क्रिप्ट में पारित सभी तर्क शामिल हैं।

मूल रूप से,

import sys
print(sys.argv[1:])

83
वास्तव में सरल सामान के लिए, यह जाने का तरीका है, हालांकि आप शायद केवल उपयोग करना चाहते हैं sys.argv[1:](स्क्रिप्ट नाम से बचा जाता है)।
Xiong Chiamiov

128

बस इन कारणों के लिए बेहतर है जो argparse के लिए प्रचार के आसपास जा रहा है .. अनिवार्य रूप से:

(लिंक से कॉपी किया गया)

  • चापलूसी मॉड्यूल स्थिति और वैकल्पिक तर्कों को संभाल सकता है, जबकि ऑप्टपर्स केवल वैकल्पिक तर्कों को संभाल सकता है

  • आपके कमांड लाइन इंटरफ़ेस की तरह क्या दिखना चाहिए, इसके बारे में argparse हठधर्मी नहीं है - आवश्यक विकल्प के रूप में -file या / file जैसे विकल्प समर्थित हैं। इन सुविधाओं का समर्थन करने से इनकार करते हैं, व्यावहारिकता पर शुद्धता पसंद करते हैं

  • argparse आपके तर्कों से निर्धारित कमांड-लाइन उपयोग सहित और अधिक जानकारीपूर्ण उपयोग संदेश उत्पन्न करता है, और स्थिति और वैकल्पिक तर्क दोनों के लिए संदेशों की मदद करता है। ऑप्टपर्स मॉड्यूल को आपको अपना उपयोग स्ट्रिंग लिखने की आवश्यकता होती है, और स्थिति संबंधी तर्कों के लिए सहायता प्रदर्शित करने का कोई तरीका नहीं है।

  • argparse ऐसी क्रिया का समर्थन करता है जो कमांड-लाइन आर्ग्स की एक चर संख्या का उपभोग करता है, जबकि ऑप्टपर्स के लिए आवश्यक है कि सटीक संख्या में तर्क (जैसे 1, 2, या 3) पहले से ज्ञात हों।

  • चापलूसी पार्सरों का समर्थन करता है जो उप-आदेशों को भेजते हैं, जबकि ऑप्टपर्स को allow_interspersed_argsमैन्युअल रूप से पार्सर प्रेषण और सेटिंग की आवश्यकता होती है

और मेरा व्यक्तिगत पसंदीदा:

  • चापलूसी प्रकार और कार्रवाई मापदंडों को add_argument() सरल कॉलबल्स के साथ निर्दिष्ट करने की अनुमति देता है , जबकि ऑप्टपर्स को हैकिंग क्लास विशेषताओं की तरह STORE_ACTIONSया CHECK_METHODSउचित तर्क की जांच करने की आवश्यकता होती है

27
यह अब मानक पायथन का हिस्सा है जैसा कि 2.7 और 3.2 :)
jpswain

"वैकल्पिक तर्क" क्या हैं? आप कहते हैं कि वे ऑप्टपर्स में हैं। मैंने सोचा था कि वे तर्क थे या प्रदान नहीं किए जा सकते हैं, लेकिन आपने कहा कि वे ऑप्टपर्स में हैं, यह कहते हुए कि "ऑप्टपर्स की आवश्यकता है कि सटीक संख्या में तर्क पहले से ज्ञात हों"। तो या तो "वैकल्पिक तर्क" की आपकी परिभाषा मेरे विचार से भिन्न है, या आपका उत्तर अपने आप में असंगत है।
ArtOfWarfare

1
बस एक पकड़: अर्गपर्स डॉक्यूमेंटेशन भी पागलपन है, पागलपन से जटिल है। आप के लिए एक सरल जवाब नहीं मिल सकता है "कैसे मैं एक कमांड लाइन तर्क को एक एकल मूल्य में लेता हूं, और मैं उस मूल्य तक कैसे पहुंच सकता हूं।" </ पकड़>
ओस्मान

2
@ ओसमैन इस कोमल ट्यूटोरियल पर हो सकता है कि अर्गपर्स मदद कर सके ...
लाइफबैलेंस

2
इस संदर्भ में @ArtOfWarfare "वैकल्पिक तर्कों" का अर्थ है कि विकल्प जैसे तर्कों के साथ निर्दिष्ट तर्क जैसे -fया --foo, जबकि "सटीक संख्या में तर्क पहले से जाना जाता है" संभवतः पूर्ववर्ती विकल्प झंडे के बिना दिए गए स्थितिगत तर्क।
मत्तुर

67

वहाँ भी है argparsestdlib मॉड्यूल (stdlib के optparseमॉड्यूल पर एक "आवेग" )। परिचय से लेकर उदाहरण के लिए :

# script.py
import argparse

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument(
        'integers', metavar='int', type=int, choices=range(10),
         nargs='+', help='an integer in the range 0..9')
    parser.add_argument(
        '--sum', dest='accumulate', action='store_const', const=sum,
        default=max, help='sum the integers (default: find the max)')

    args = parser.parse_args()
    print(args.accumulate(args.integers))

उपयोग:

$ script.py 1 2 3 4
4

$ script.py --sum 1 2 3 4
10

1
इसकी सिर्फ एक कॉपी और पेस्ट
blitu12345

3
@ मेरे उत्तर के प्रकाशन के समय blitu12345 कोई अन्य उत्तर नहीं थे जो किसी भी तरह से विवाद का उल्लेख करते हों। मॉड्यूल स्वयं stdlib¶ में नहीं था। आपके पास प्रलेखन से कोड उदाहरणों के खिलाफ क्या है? आपको क्या लगता है कि मॉड्यूल के लेखक द्वारा प्रदान किए गए उदाहरणों के बजाय अपने स्वयं के उदाहरणों के साथ आना आवश्यक है? और मुझे लिंक-ओनली उत्तर (मैं अकेला नहीं हूँ) पसंद नहीं है।
JFS

1
यहाँ आने वाले लोगों को पहले से ही एक विचार था कि दस्तावेज़ीकरण में क्या है और केवल विषय के बारे में आगे की मंजूरी के लिए यहां होगा। मेरा मामला था, लेकिन जो मुझे वास्तव में यहाँ मिला वह मूल डॉक्स से कॉपी और पेस्ट है।
blitu12345

2
"यहां आने वाले लोगों को पहले से ही प्रलेखन में एक विचार था" - मुझे बहुत संदेह है कि धारणा है। किसी न किसी तरह।
sjas

49

इसका उपयोग करने का एक तरीका है sys.argv। यह स्क्रिप्ट नाम को पहले तर्क और उन सभी अन्य मापदंडों के रूप में प्रिंट करेगा जो आप इसे पास करते हैं।

import sys

for arg in sys.argv:
    print arg

49

Docopt पुस्तकालय वास्तव में चालाक है। यह आपके ऐप के लिए उपयोग स्ट्रिंग से एक तर्क का निर्माण करता है।

डॉकटॉप रीडमे से उदाहरण:

"""Naval Fate.

Usage:
  naval_fate.py ship new <name>...
  naval_fate.py ship <name> move <x> <y> [--speed=<kn>]
  naval_fate.py ship shoot <x> <y>
  naval_fate.py mine (set|remove) <x> <y> [--moored | --drifting]
  naval_fate.py (-h | --help)
  naval_fate.py --version

Options:
  -h --help     Show this screen.
  --version     Show version.
  --speed=<kn>  Speed in knots [default: 10].
  --moored      Moored (anchored) mine.
  --drifting    Drifting mine.

"""
from docopt import docopt


if __name__ == '__main__':
    arguments = docopt(__doc__, version='Naval Fate 2.0')
    print(arguments)

4
यह तेजी से मेरा पसंदीदा तरीका बन गया है। यह स्ट्रिंग पार्सिंग है इसलिए यह भंगुर है, लेकिन यह सभी एक जगह पर भंगुर है और आप try.docopt.org पर अपने तर्क का पूर्वावलोकन कर सकते हैं । वैकल्पिक और पारस्परिक रूप से अनन्य तर्क वास्तव में सुरुचिपूर्ण तरीके से किए जाते हैं।
गॉवसेय

4
मैं naval_fate.py के लिए बाकी कोड देखने के लिए बेताब हूं
John Lawrence Aspden

48

अगर आपको कुछ तेज चाहिए और बहुत लचीला नहीं है

main.py:

import sys

first_name = sys.argv[1]
last_name = sys.argv[2]
print("Hello " + first_name + " " + last_name)

फिर भागो python main.py James Smith

निम्नलिखित उत्पादन का उत्पादन करने के लिए:

नमस्कार जेम्स स्मिथ


एक और अधिक यथार्थवादी उपयोग किया जाएगा python main.py "James Smith"जो पुट James Smithमें sys.argv[1]और एक का उत्पादन IndexErrorजब आप अस्तित्वहीन इस्तेमाल करने की कोशिश sys.argv[2]। कोटिंग व्यवहार कुछ हद तक इस बात पर निर्भर करेगा कि आप किस प्लेटफॉर्म और शेल से पायथन चलाते हैं।
ट्रिपलए

10
मैं इस बात से सहमत नहीं हूं कि मेरा उपयोग कम यथार्थवादी है। अपने कार्यक्रम को किसी व्यवसाय में स्क्रिप्ट को चलाने के लिए किसी व्यक्ति के सटीक पहले और अंतिम नाम को जानने की जरूरत है, जहां लोगों के कई पहले और अंतिम नाम हो सकते हैं? यदि जेम्स स्मिथ के पास जोसफ के पास एक अतिरिक्त पहला या अंतिम नाम है, तो इस बात में अंतर कैसे होगा कि जोसेफ केवल एक अतिरिक्त या अंतिम नाम है या नहीं python main.py "James Joseph Smith"? यदि आप सीमा से बाहर सूचकांक से संबंधित हैं, तो आप प्रदान किए गए तर्कों की संख्या के लिए एक चेक जोड़ सकते हैं। कम यथार्थवादी या नहीं, मेरा उदाहरण दिखाता है कि कई तर्कों को कैसे संभालना है।
केंट मुन्थे कैस्परसन

1
अन्य सभी उत्तर चंद्र लैंडिंग मिशन की साजिश रचने के लिए हैं। मैं बस प्रयोग कर रहा हूं gmail-trash-msg.py MessageID। यह उत्तर परीक्षण MessageIDपैरामीटर के लिए सीधे आगे भेजा गया है sys.argv[1]
विनयुनुच्स 2 यूनिक्स

26
#set default args as -h , if no args:
if len(sys.argv) == 1: sys.argv[1:] = ["-h"]

19

मैं अपने आप को ऑप्टपर्स का उपयोग करता हूं, लेकिन वास्तव में साइमन विलिसन अपने हाल ही में शुरू किए गए ऑप्टोफंक लाइब्रेरी के साथ दिशा ले रहा है । यह इसके द्वारा काम करता है:

"एक फ़ंक्शन परिभाषा (इसके तर्कों और उनके डिफ़ॉल्ट मूल्यों सहित) का आत्मनिरीक्षण करना और कमांड लाइन तर्क पार्सर के निर्माण के लिए इसका उपयोग करना।"

इसलिए, उदाहरण के लिए, इस फ़ंक्शन की परिभाषा:

def geocode(s, api_key='', geocoder='google', list_geocoders=False):

इस ऑप्टपर्स सहायता पाठ में बदल जाता है:

    Options:
      -h, --help            show this help message and exit
      -l, --list-geocoders
      -a API_KEY, --api-key=API_KEY
      -g GEOCODER, --geocoder=GEOCODER

8

मुझे stdlib से गेटअप पसंद है, जैसे:

try:
    opts, args = getopt.getopt(sys.argv[1:], 'h', ['help'])
except getopt.GetoptError, err: 
    usage(err)

for opt, arg in opts:
    if opt in ('-h', '--help'): 
        usage()

if len(args) != 1:
    usage("specify thing...")

हाल ही में मैं कुछ चीज़ों को कम करने के लिए इस तरह से कुछ लपेट रहा हूं (उदाहरण के लिए, "-h" निहित)।


8

Pocoo का क्लिक अधिक सहज है, कम बॉयलरप्लेट की आवश्यकता होती है, और कम से कम उतना ही शक्तिशाली है जितना कि argparse।

केवल कमजोरी मैं अब तक का सामना करना पड़ा है कि आप मदद पृष्ठों के लिए बहुत कुछ अनुकूलन नहीं कर सकता है, लेकिन है कि आमतौर पर एक आवश्यकता नहीं है और docopt स्पष्ट विकल्प की तरह लगता है जब यह है।


7

जैसा कि आप ऑप्टपर्स को देख सकते हैं "ऑप्टपर्स मॉड्यूल के साथ पदावनत किया जाता है और इसे आगे विकसित नहीं किया जाएगा, अर्गपर्स मॉड्यूल के साथ विकास जारी रहेगा ।"


5
import argparse

parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('integers', metavar='N', type=int, nargs='+',
                   help='an integer for the accumulator')
parser.add_argument('--sum', dest='accumulate', action='store_const',
                   const=sum, default=max,
                   help='sum the integers (default: find the max)')

args = parser.parse_args()
print(args.accumulate(args.integers))

Assuming the Python code above is saved into a file called prog.py
$ python prog.py -h

Ref-link: https://docs.python.org/3.3/library/argparse.html

4

आप एक छोटे अजगर मॉड्यूल में दिलचस्पी ले सकते हैं, जिसे मैंने कमांड लाइन के तर्कों को और भी आसान बनाने के लिए लिखा था (खुला स्रोत और उपयोग करने के लिए स्वतंत्र) - कमांडो


1
पहले से ही कमांडो नाम का एक और कमांड-लाइन पार्सिंग मॉड्यूल है: github.com/lakshmivyas/commando । यह डेकोरेटर्स का उपयोग करके अर्गपर्स को लपेटता है।
रॉबर्टो बोनावलेट 15

1
अजगर और पहिया फिर से आविष्कार
डेरेक

4

मैं इन दूसरों के लिए एक सरल विकल्प के रूप में डॉकटॉप को देखने की सलाह देता हूं ।

docopt एक नई परियोजना है जो आपको अपना सब कुछ लागू करने की आवश्यकता के बजाय आपके --help उपयोग संदेश को पार्स करके काम करती है। आपको बस अपना उपयोग संदेश POSIX प्रारूप में रखना होगा।


4

फिर भी एक और विकल्प अर्ग है । यह argparse पर बनाता है, और आपको इस तरह की चीजें लिखने देता है:

import argh

# declaring:

def echo(text):
    "Returns given word as is."
    return text

def greet(name, greeting='Hello'):
    "Greets the user with given name. The greeting is customizable."
    return greeting + ', ' + name

# assembling:

parser = argh.ArghParser()
parser.add_commands([echo, greet])

# dispatching:

if __name__ == '__main__':
    parser.dispatch()

यह स्वचालित रूप से सहायता और इतने पर उत्पन्न करेगा, और आप सज्जाकार का उपयोग अतिरिक्त मार्गदर्शन प्रदान करने के लिए कर सकते हैं कि कैसे आर्ग-पार्सिंग को काम करना चाहिए।


यह सबसे अच्छा उपाय है। उपयोग करना arghदूसरे कामों की तुलना में आसान है या उपयोग करना sys
जुआनजो साल्वाडोर

मैं पसंद करना चाहता था, arghलेकिन यह उन परिदृश्यों के लिए विशेष रूप से उपयुक्त नहीं है, जहां आपकी अत्यधिक इच्छा सबकोमांड के साथ कमांड रखने की नहीं है।
ट्रिपलए

1
@tripleee YMMV, लेकिन मैंने पाया कि यह केवल लाइब्रेरी की तुलना में प्रलेखन में एक खराबी थी। यह def frobnicate_spleches(...)एक फ़ंक्शन को परिभाषित करने के लिए पूरी तरह से संभव लगता है जो आपकी स्क्रिप्ट को जो कुछ भी करता है, if __name__ == '__main__': argh.dispatch_command(frobnicate_spleches)वह फ़ाइल के अंत में कर रहा है।
परिपत्र-

0

मेरा समाधान प्रविष्टि 2 है । उदाहरण:

from entrypoint2 import entrypoint
@entrypoint
def add(file, quiet=True): 
    ''' This function writes report.

    :param file: write report to FILE
    :param quiet: don't print status messages to stdout
    '''
    print file,quiet

मदद पाठ:

usage: report.py [-h] [-q] [--debug] file

This function writes report.

positional arguments:
  file         write report to FILE

optional arguments:
  -h, --help   show this help message and exit
  -q, --quiet  don't print status messages to stdout
  --debug      set logging level to DEBUG
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.