Komut satırı argümanları nasıl okunur / işlenir?


623

5
Docopt kullanın (@ ralbatross'un stackoverflow.com/a/14790373/116891 adresindeki cevaba bakın ). Diğer her şekilde denedim ve gerçekten, ileride kullanacağım tek docopt.
Pat

2
En iyi tek yol olduğunu düşünmüyorum. argparse standart ve özelliklidir. docopt çok zarif ama standart kütüphanede değil. Çok kolay hafif kullanım için fonksiyon varsayılan değerlerini sizin için comand line argüman varsayılanlarını işleyebilirsiniz .
Simon Hibbs

Yanıtlar:


456

Standart kütüphanedeki standart çözüm argparse( dokümanlar ):

İşte bir örnek:

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 destekler (diğer şeylerin yanı sıra):

  • Herhangi bir sırayla çoklu seçenekler.
  • Kısa ve uzun seçenekler.
  • Varsayılan değerler.
  • Bir kullanım yardım mesajı oluşturulması.

27
Evet, bunlar en iyisi. Standart kütüphanenin bir parçası olduklarından, kullanılabilir olduklarından ve kullanımı kolay olduklarından emin olabilirsiniz. optparse özellikle güçlü ve kolaydır.
Barry Wark

4
optparse en iyilerinden biridir; getopt eskidir ve gerçekten kullanımdan kaldırılmış sayılmalıdır.
jemfinch

12
bu noktada (12/2011), argparse artık optparse'dan daha iyi bir seçenek olarak kabul ediliyor, değil mi?
oob

54
Python Documentation, optparse yerine argparse kullanımını önermektedir.
15'te

7
Kullanımdan optparsekaldırıldığı için, sorunun askerleri artık yığın taşmasına üye değildir ve bu oldukça görünür bir soru için kabul edilen cevaptır - lütfen argparsebunun yerine stdlib kullanmak için örnek kodunuzu tamamen yeniden yazmayı düşünün .
wim

548
import sys

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

sys.argv komut satırında komut dosyasına iletilen tüm bağımsız değişkenleri içeren bir listedir.

Temel olarak,

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

83
Gerçekten basit şeyler için, bu sadece gitmek istediğiniz yol olsa da sys.argv[1:], komut dosyası adından kaçınır).
Xiong Chiamiov

128

Sadece bu nedenlerle daha iyi olan argparse için evangelize etmek.

(bağlantıdan kopyalandı)

  • argparse modülü konumsal ve isteğe bağlı bağımsız değişkenleri işlerken optparse yalnızca isteğe bağlı bağımsız değişkenleri işleyebilir

  • argparse, komut satırı arayüzünüzün nasıl görünmesi gerektiği konusunda dogmatik değildir - gerekli seçenekler gibi -file veya / file gibi seçenekler desteklenir. Optparse, pratiklik yerine saflığı tercih ederek bu özellikleri desteklemeyi reddediyor

  • argparse, bağımsız değişkenlerinizden belirlenen komut satırı kullanımı ve hem konumsal hem de isteğe bağlı bağımsız değişkenler için yardım iletileri de dahil olmak üzere daha bilgilendirici kullanım iletileri üretir. Optparse modülü, kendi kullanım dizenizi yazmanızı gerektirir ve konumsal bağımsız değişkenler için yardımı görüntülemenin bir yolu yoktur.

  • argparse, değişken sayıda komut satırı argümanı tüketen eylemi destekler, optparse ise tam bağımsız değişken sayısının (örn. 1, 2 veya 3) önceden bilinmesini gerektirir

  • argparse, alt komutlara gönderilen ayrıştırıcıları destekler; optparse allow_interspersed_argsise ayrıştırıcı dağıtımını manuel olarak ayarlamayı ve yapmayı gerektirir

Ve benim kişisel favorim:

  • argparse, tür ve eylem parametrelerinin add_argument() basit callables ile belirtilmesine izin verirken, optparse gibi sınıf özniteliklerini hacklemek STORE_ACTIONSveya CHECK_METHODSuygun bağımsız değişken denetimi almak için

27
Bu artık 2.7 ve 3.2'den itibaren standart Python'un bir parçası :)
jpswain

"İsteğe bağlı argümanlar" nedir? Dediler. Bunların sağlanabilecek ya da sağlanamayabilecek argümanlar olduğunu düşündüm, ama “optparse, kesin argüman sayısının önceden bilinmesini gerektiriyor” demeye devam ederken, iyimser olduklarını söylediniz. Yani ya “isteğe bağlı argüman” tanımınız düşündüğümden farklı ya da cevabınız kendisiyle tutarsız.
ArtOfWarfare

1
Sadece bir yakınma: argparse belgeleri delicesine, delicesine karmaşık. "Komut satırı bağımsız değişkenini tek bir değerde nasıl alabilirim ve bu değere nasıl erişebilirim" için basit bir yanıt alamazsınız. </gripe>
osman

2
@osman Tartparse üzerine bu nazik öğretici yardımcı olabilir ...
lifebalance

2
@ArtOfWarfare bu bağlamda "isteğe bağlı bağımsız değişkenler" muhtemelen -fveya gibi seçenek benzeri bağımsız değişkenlerle belirtilen bağımsız değişkenler anlamına --foogelirken, "önceden tam bağımsız değişken sayısı biliniyor", muhtemelen önceki seçenek bayrakları olmadan verilen konumsal bağımsız değişkenler anlamına gelir.
mtraceur

67

Ayrıca argparsestdlib modülü de vardır ( stdlib modülünde bir "gelişme" optparse). Örnek giriş argparse için :

# 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))

Kullanımı:

$ script.py 1 2 3 4
4

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

1
Bu sadece bir kopyala ve yapıştır
blitu12345

3
@ blitu12345 Cevabımın yayınlandığı sırada hiçbir şekilde argparse'den bahseden başka cevap yoktu. Modülün kendisi stdlib'de değildi¶ Belgelerdeki kod örneklerine karşı neyiniz var? Neden modülün yazarı tarafından verilen örnekler yerine kendi örneklerinizi bulmanız gerektiğini düşünüyorsunuz? Ve sadece bağlantı cevaplarını sevmiyorum (yalnız değilim).
jfs

1
Buraya gelen halklar zaten belgelerde bir fikir vardı ve sadece konu hakkında daha fazla boşluk için burada olacaklar.
blitu12345

2
"Buraya gelen halklar zaten belgelerinde ne bir fikir vardı" - bu varsayım son derece şüpheliyim. bir şekilde.
sjas

49

Bunu yapmanın bir yolu kullanmaktır sys.argv. Bu, komut dosyası adını ilk bağımsız değişken ve ona ilettiğiniz tüm diğer parametreler olarak yazdırır.

import sys

for arg in sys.argv:
    print arg

49

Docopt kütüphanesi gerçekten kaygan. Uygulamanızın kullanım dizesinden bir bağımsız değişken diktesi oluşturur.

Örneğin, docopt benioku dosyasından:

"""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
Bu benim en sevdiğim yol haline geldi. Dize ayrıştırmadır, bu yüzden biraz kırılgandır, ancak hepsi tek bir yerde kırılgandır ve mantığınızı try.docopt.org'da önizleyebilirsiniz . İsteğe bağlı ve birbirini dışlayan argümanlar gerçekten zarif bir şekilde yapılır.
gvoysey

4
Naval_fate.py kodunun geri kalanını görmek için umutsuzum
John Lawrence Aspden

48

Hızlı ve çok esnek olmayan bir şeye ihtiyacınız varsa

main.py:

import sys

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

O zaman koş python main.py James Smith

Aşağıdaki çıktıyı üretmek için:

Merhaba James Smith


Daha gerçekçi kullanım olacağını python main.py "James Smith"hangi koyar James Smithiçinde sys.argv[1]ve bir üretir IndexErrorEğer varolmayan kullanmaya çalıştığınızda sys.argv[2]. Alıntı yapma davranışı, Python'u hangi platformdan ve kabuğundan çalıştırdığınıza bağlı olacaktır.
tripleee

10
Kullanımımın daha az gerçekçi olduğuna katılmıyorum. Programınızın, insanların birden fazla ad ve soyadı olabileceği bir işletmede komut dosyasını çalıştırmak için bir kişinin tam adını ve soyadını bilmesi gerekir mi? James Smith, Joseph'e fazladan bir ad mı yoksa soyadı olarak sahipse, Joseph'in sadece bir ad mı yoksa soyadı mı olduğunu nasıl ayırt edersiniz python main.py "James Joseph Smith"? Dizinin sınırların dışında olmasıyla ilgileniyorsanız, sağlanan bağımsız değişkenlerin sayısı için bir kontrol ekleyebilirsiniz. Daha az gerçekçi ya da değil, örneğim birden çok argümanın nasıl ele alınacağını gösterir.
Kent Munthe Caspersen

1
Diğer tüm cevaplar bir ay iniş görevi planlamak içindir. Sadece kullanıyorum gmail-trash-msg.py MessageID. Bu cevap test MessageIDparametresinin geçildiğini iletmek için basittir sys.argv[1].
WinEunuuchs2Unix

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

19

Kendimi optparse kullanıyorum, ama Simon Willison'un yakın zamanda tanıttığı optfunc kütüphanesinde izlediği yön gibi . Şununla çalışır:

"bir işlev tanımının (argümanları ve varsayılan değerleri dahil) introspeksiyon ve bunu komut satırı bağımsız değişken ayrıştırıcısı oluşturmak için kullanma."

Örneğin, bu işlev tanımı:

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

bu optparse yardım metnine dönüştürülür:

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

8

Ben stdlib gelen getopt gibi, örneğin:

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...")

Son zamanlarda, işleri daha az ayrıntılı yapmak için buna benzer bir şey sarıyorum (örneğin, "-h" örtük yapmak).


8

Pocoo'nun tıklaması daha sezgisel, daha az kaynatma plakası gerektiriyor ve en azından argparse kadar güçlü.

Şimdiye kadar karşılaştığım tek zayıf nokta, sayfalara yardım etmek için fazla özelleştirme yapamamanız, ancak bu genellikle bir gereklilik değildir ve docopt , açık bir seçim gibi görünüyor.


7

Gördüğünüz gibi optparse "Optparse modülü kullanımdan kaldırılmıştır ve daha fazla geliştirilmeyecektir; geliştirme, argparse modülüyle devam edecektir ."


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

Komut satırı argümanlarının işlenmesini daha da kolaylaştırmak için yazdığım küçük bir Python modülüyle ilgilenebilirsiniz (açık kaynak ve kullanımı ücretsiz) - Commando


1
Commando adında başka bir komut satırı ayrıştırma modülü var: github.com/lakshmivyas/commando . Arpatörleri dekoratörler kullanarak sarar.
Roberto Bonvallet

1
python ve tekerlek yeniden icadı
Derek

4

Ben bakmanızı öneririz docopt bu başkalarına basit bir alternatif olarak.

docopt, her şeyi kendiniz uygulamanızı gerektirmek yerine --help kullanım mesajınızı ayrıştırarak çalışan yeni bir projedir. Kullanım mesajınızı POSIX biçiminde koymanız yeterlidir.


4

Yine başka bir seçenek argh . Argparse üzerine kuruludur ve aşağıdaki gibi şeyler yazmanıza izin verir:

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()

Otomatik olarak yardım vb. Üretecektir ve arg-ayrıştırma işleminin nasıl çalışması gerektiği konusunda ek rehberlik sağlamak için dekoratörleri kullanabilirsiniz.


Bu en iyi çözüm. Kullanımı arghbaşka bir kütüphaneden daha kolaydır sys.
Juanjo Salvador

Sevmek istedim, arghancak en büyük arzunuzun alt komutlarla bir komuta sahip olmak olmadığı senaryolar için özellikle uygun değil.
tripleee

1
@tripleee YMMV, ama bunun kütüphane içinde olduğundan daha çok dokümantasyonda bir kusur olduğunu gördüm. def frobnicate_spleches(...)Komut dosyanızın yaptığı her şeyi yapan bir işlevi tanımlamak, ardından if __name__ == '__main__': argh.dispatch_command(frobnicate_spleches)dosyanın sonunda yapmak mükemmel bir şekilde mümkün görünüyor .
dairesel harabe

0

Benim çözümüm giriş noktası2 . Misal:

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

Yardım Metni:

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.