İstenen basit argparse örneği: 1 argüman, 3 sonuç


529

Dokümantasyon için argparse piton modülü benim küçük acemi beyin şu anda kavramak için eminim mükemmel iken, çok fazla. Komut satırında matematik yapmam ya da ekrandaki satırları biçimlendirmem ya da seçenek karakterlerini değiştirmem gerekmiyor. Tek yapmak istediğim şey "arg, A ise bunu yap, eğer B bunu yaparsa, yukarıdakilerin hiçbiri yardım göstermez ve çıkmaz" .


15
o sys.argvzaman istediğiniz argümanı kontrol edin ...
JBernardo

10
Hiç plasmanı denediniz mi? Harika belgelerle argparse üzerinde kullanımı kolay bir sarıcı .
kirbyfan64sos

157
sen değilsin. bu argparse. sizi yıldızlara doğru bir yolculuğa çıkarmaya çalışıyor ve nereye gittiğinizle ilgilenmiyor.
Florian Heigl

11
Çılgın "pythonic" API'leri tekrar: /
mlvljr

69
Her yerde küçük acemi beyinleri için ayağa kalktığınız için matt wilkie'yi korusun.
polka

Yanıtlar:


255

Orijinal soru hakkındaki anlayışım iki yönlü. İlk olarak, mümkün olan en basit argparse örneği açısından, burada görmediğime şaşırdım. Tabii ki, ölü-basit olmak için, hepsi de az bir güçle tepegöz, ama başlayabilirsin.

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("a")
args = parser.parse_args()

if args.a == 'magic.name':
    print 'You nailed it!'

Ancak bu konumsal argüman artık gerekli. Bu programı çağırırken programı dışarıda bırakırsanız, eksik argümanlar hakkında bir hata alırsınız. Bu beni orijinal sorunun ikinci kısmına götürüyor. Matt Wilkie , adlandırılmış etiketi olmayan ( isteğe bağlı etiketler) tek bir isteğe bağlı bağımsız değişken istiyor gibi görünüyor . Benim önerim yukarıdaki kodu aşağıdaki gibi değiştirmek olacaktır:

...
parser.add_argument("a", nargs='?', default="check_string_for_empty")
...
if args.a == 'check_string_for_empty':
    print 'I can tell that no argument was given and I can deal with that here.'
elif args.a == 'magic.name':
    print 'You nailed it!'
else:
    print args.a

Daha zarif bir çözüm olabilir, ancak bu işe yarar ve minimalisttir.


4
Bir süre yansıtıldıktan sonra, bu soruyu gerçekten Q'nun istendiği gibi ve o sırada bulunduğum öngörüleri en iyi cevapladığı sonucuna varıyorum. Diğer mükemmel cevaplar, değerlerini kanıtlamak için fazlasıyla yeterli temsil aldı ve biraz rekabet edebilir. :-)
matt wilkie

@badnack: Olmasını istediğiniz her şey, 'a' neyi temsil ediyorsa. Bir bağımsız değişken, örneğin bir dosya adı bekliyorsanız, komut satırına dosya adı olarak girilen addır. Daha sonra dosya sisteminde var olup olmadığını belirlemek için kendi işleminizi yapabilirsiniz, ancak bu başka bir Soru-Cevap.
mightypile

363

Ben argparse(çoklu argüman ile) ile bunu yapmanın yolu :

parser = argparse.ArgumentParser(description='Description of your program')
parser.add_argument('-f','--foo', help='Description for foo argument', required=True)
parser.add_argument('-b','--bar', help='Description for bar argument', required=True)
args = vars(parser.parse_args())

args şu bağımsız değişkenleri içeren bir sözlük olacaktır:

if args['foo'] == 'Hello':
    # code here

if args['bar'] == 'World':
    # code here

Sizin durumunuzda sadece bir argüman ekleyin.


3
diğer cevaba yaptığım yorumda belirtildiği gibi, argparse'ın otomatik yardım biçimlendirmesini tutmak istiyorum, ancak isimsiz bir argümana sahip olmak için bir seçenek yok gibi görünüyor (muhtemelen gördüğümde anlamıyorum ), örneğin birinin yapması foo.py --action installveya foo.py --action removebasitçe yerinefoo.py install
matt wilkie

7
@mattwilkie O zaman böyle bir konumsal argüman tanımlamanız gerekir: parser.add_argument('install', help='Install the app') ( Konumsal bir argüman tanımlayamayacağınıza dikkat edin required=True)
Diego Navarro

32
Tartışmak için bir noob olarak, bu cevap gerçekten yardımcı oldu çünkü seçenekleri geçtikten sonra nerede bulacağımı bilmiyordum . Başka bir deyişle, argsdiktenin yukarıdaki gibi nasıl oluşturulduğunu anlamam gerekiyordu .
mrKelley

3
Programı doğrudan komut satırından çağırırken 'kısa form' ve bir kod içinde bir program / komut çalıştırdığınızda 'uzun form' kullanın. Bu durumda, uzun formla daha insan tarafından okunabilir ve dolayısıyla kodun / komut dosyasının mantığını izlemek daha kolaydır.
ola

17
Şahsen olarak erişim argümanları temizleyici bulmak args.foove args.baryerine sözlük sözdizimi. Her iki durumda da elbette iyidir, ancak argümanlar aslında bir sözlük değil, bir argparse.Namespacenesnedir.
Michael Mior

210

argparseDokümantasyon oldukça iyi ama birkaç yararlı detaylar dışında yapraklar hangi belirgin olmayabilir. (@Diego Navarro bundan biraz bahsetti ama cevabını biraz genişletmeye çalışacağım.) Temel kullanım aşağıdaki gibidir:

parser = argparse.ArgumentParser()
parser.add_argument('-f', '--my-foo', default='foobar')
parser.add_argument('-b', '--bar-value', default=3.14)
args = parser.parse_args()

Geri döndüğünüz nesne parse_args()bir 'Ad Alanı' nesnesidir: Üye değişkenleri komut satırı argümanlarınızdan sonra adlandırılan bir nesne. NamespaceNesne Eğer argümanları ve bunlarla ilişkili değerlere erişir nasıl:

args = parser.parse_args()
print args.my_foo
print args.bar_value

( argparseDeğişkenleri adlandırırken bağımsız değişken adlarınızdaki '-' karakterinin alt çizgi ile değiştirildiğini unutmayın .)

Birçok durumda, argümanları basitçe değeri olmayan bayraklar olarak kullanmak isteyebilirsiniz. Bunları argparse'ta şu şekilde ekleyebilirsiniz:

parser.add_argument('--foo', action='store_true')
parser.add_argument('--no-foo', action='store_false')

Yukarıdaki, sırasıyla True değerine sahip 'foo' ve False değerine sahip 'no_foo' adlı değişkenler oluşturur:

if (args.foo):
    print "foo is true"

if (args.no_foo is False):
    print "nofoo is false"

Bağımsız değişken eklerken "zorunlu" seçeneğini kullanabileceğinizi de unutmayın:

parser.add_argument('-o', '--output', required=True)

Bu şekilde, komut satırında bu bağımsız değişkeni atlarsanız, argparseeksik olduğunu söyler ve komut dosyanızın yürütülmesini durdurur.

Son olarak, varseğer hayatı sizin için kolaylaştırırsa , fonksiyonu kullanarak argümanlarınızın dikte yapısını oluşturmanın mümkün olduğunu unutmayın .

args = parser.parse_args()
argsdict = vars(args)
print argsdict['my_foo']
print argsdict['bar_value']

Gördüğünüz gibi vars, argüman adlarınızı anahtarlar ve değerlerini er, değerler olarak içeren bir diksiyon döndürür.

Yapabileceğiniz başka birçok seçenek ve şey var, ancak bu en önemli, yaygın kullanım senaryolarını kapsamalıdır.


3
Ne anlamı var '-f've '-b'? Bunu neden atlayamıyorsun?
user2763361

13
Her çalışma zamanı seçeneği için hem 'kısa form' (bir çizgi) hem de 'uzun form' (iki çizgi) sürümüne sahip olmak oldukça gelenekseldir. Örneğin, hemen hemen her standart Unix / Linux yardımcı programında bunu göreceksiniz; Bir yapmak man cpya man lsve birçok seçenek hem tatlar (örneğin gelir olduğunu göreceksiniz -f, --force). İnsanların birini veya diğerini tercih etmelerinin büyük olasılıkla çok çeşitli nedenleri vardır, ancak her durumda her iki formu da programınızda kullanılabilir hale getirmek oldukça standarttır.
DMH

59

Matt, argparse'deki pozisyon parametrelerini soruyor ve Python belgelerinin bu açıdan eksik olduğunu kabul ediyorum. ~ 20 tek sayfada, hem ayrıştırma hem de konum parametrelerini gösteren tek ve tam bir örnek yoktur .

Buradaki diğer cevapların hiçbiri tam bir konumsal parametre örneği göstermiyor, bu yüzden tam bir örnek:

# tested with python 2.7.1
import argparse

parser = argparse.ArgumentParser(description="An argparse example")

parser.add_argument('action', help='The action to take (e.g. install, remove, etc.)')
parser.add_argument('foo-bar', help='Hyphens are cumbersome in positional arguments')

args = parser.parse_args()

if args.action == "install":
    print("You asked for installation")
else:
    print("You asked for something other than installation")

# The following do not work:
# print(args.foo-bar)
# print(args.foo_bar)

# But this works:
print(getattr(args, 'foo-bar'))

Beni atmış olan şey, argparse adlı "--foo-bar" adlı bağımsız değişkeni "foo_bar" a dönüştürecek, ancak "foo-bar" adlı konumsal bir parametrenin "foo-bar" olarak kalacağı, programınızda kullanın.

Örneğimin sonuna yakın iki çizgiye dikkat edin - bunların hiçbiri foo-bar konumsal parametresinin değerini elde etmek için çalışmaz. Birincisi açıkça yanlış (argsmetic ifadesi args.foo eksi çubuğu), ancak ikincisi de çalışmıyor:

AttributeError: 'Namespace' object has no attribute 'foo_bar'

foo-barÖzniteliği kullanmak istiyorsanız , getattrörneğimin son satırında görüldüğü gibi kullanmalısınız . Çılgın dest=foo_barolan şey, özellik adını erişmek daha kolay bir şeyle değiştirmek için kullanmayı denerseniz, gerçekten tuhaf bir hata mesajı alırsınız:

ValueError: dest supplied twice for positional argument

Yukarıdaki örnek şu şekilde çalışır:

$ python test.py
usage: test.py [-h] action foo-bar
test.py: error: too few arguments

$ python test.py -h
usage: test.py [-h] action foo-bar

An argparse example

positional arguments:
  action      The action to take (e.g. install, remove, etc.)
  foo-bar     Hyphens are cumbersome in positional arguments

optional arguments:
  -h, --help  show this help message and exit

$ python test.py install foo
You asked for installation
foo


Bir konumun foo-bardönüştürülmemesi gerçeği bugs.python.org/issue15125foo_bar adresinde ele alınmaktadır .
hpaulj

2
Bu hata için daha kolay bir çözüm sadece "foo-bar" yerine "foo_bar" argümanı çağırmak olduğunu düşünüyorum, sonra print args.foo_barçalışır. Bu konumsal bir bağımsız değişken olduğundan, komut dosyasını çağırırken adı belirtmeniz gerekmez, bu nedenle kullanıcı için önemli değildir.
luator

@luator Haklısın, tartışmayı yeniden adlandırmak kolaydır, ancak hata raporunun yazarı, gereksiz bilişsel yük nedeniyle bunun hala bir yanlışlık olduğunu iyi bir şekilde ortaya koymaktadır. Argparse kullanırken, seçenekler ve argümanlar için farklı adlandırma kurallarını duraklatmalı ve hatırlamalıdır. Bkz. Bugs.python.org/msg164968 .
Mark E. Haase

1
@mehaase Bunun düzeltilmesi gereken bir yanlışlık olduğuna tamamen katılıyorum. Ben sadece argümanı yeniden adlandırmak kullanmak zorunda daha kolay ve daha az kafa karıştırıcı bir geçici çözüm olduğunu getattrdüşünüyorum (ayrıca değeri kullanan kodu değiştirmek zorunda kalmadan bir argüman isteğe bağlı yerine konum değiştirmenize izin verir gibi daha esnektir).
luator

22

Bu yazıdan esinlenen bir başka özet giriş .

import argparse

# define functions, classes, etc.

# executes when your script is called from the command-line
if __name__ == "__main__":

    parser = argparse.ArgumentParser()
    #
    # define each option with: parser.add_argument
    #
    args = parser.parse_args() # automatically looks at sys.argv
    #
    # access results with: args.argumentName
    #

Bağımsız değişkenler aşağıdakilerin kombinasyonları ile tanımlanır:

parser.add_argument( 'name', options... )              # positional argument
parser.add_argument( '-x', options... )                # single-char flag
parser.add_argument( '-x', '--long-name', options... ) # flag with long name

Ortak seçenekler:

  • help : --helpkullanıldığında bu arg için açıklama .
  • default : arg atlanırsa varsayılan değer.
  • tür : bir floatveya int(aksi halde str) bekliyorsanız.
  • dest : bir bayrağa farklı bir ad verin (örneğin '-x', '--long-name', dest='longName').
    Not: varsayılan --long-nameolarakargs.long_name
  • eylem : belirli argümanların özel olarak ele alınması için
    • store_true, store_false: boolean args için
      '--foo', action='store_true' => args.foo == True
    • store_const: seçenekle kullanılacakconst
      '--foo', action='store_const', const=42 => args.foo == 42
    • count: olduğu gibi tekrarlanan seçenekler için./myscript.py -vv
      '-v', action='count' => args.v == 2
    • append: olduğu gibi tekrarlanan seçenekler için./myscript.py --foo 1 --foo 2
      '--foo', action='append' => args.foo == ['1', '2']
  • gerekli : bir bayrak gerekiyorsa veya konumsal bir bağımsız değişken gerekli değilse.
  • nargs : bir bayrak için N argüman yakalaması
    ./myscript.py --foo a b => args.foo = ['a', 'b']
  • Seçenekler : olası girişleri kısıtlamak için (dizeler listesi veya ints olarak belirtin type=int).

12

Not Argparse Eğitimi yılında Python NASIL'larına . Bunun gibi en temel örneklerden başlar:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
                    help="display a square of a given number")
args = parser.parse_args()
print(args.square**2)

ve daha az temel olanlara ilerler.

Sorulanlar gibi, bir seçenek için önceden tanımlanmış bir seçime sahip bir örnek vardır:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
                    help="display a square of a given number")
parser.add_argument("-v", "--verbosity", type=int, choices=[0, 1, 2],
                    help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
    print("the square of {} equals {}".format(args.square, answer))
elif args.verbosity == 1:
    print("{}^2 == {}".format(args.square, answer))
else:
    print(answer)

Dokümanların güncellendiğini görmek güzel. OP'nin 5 yıl önce soruyu yayınlamasının böyle olmadığını temin ederim.
ntwrkguru

10

Temelde @DMH sayesinde öğrenme projemde ortaya koyduğum şey ...

Demo kodu:

import argparse

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-f', '--flag', action='store_true', default=False)  # can 'store_false' for no-xxx flags
    parser.add_argument('-r', '--reqd', required=True)
    parser.add_argument('-o', '--opt', default='fallback')
    parser.add_argument('arg', nargs='*') # use '+' for 1 or more args (instead of 0 or more)
    parsed = parser.parse_args()
    # NOTE: args with '-' have it replaced with '_'
    print('Result:',  vars(parsed))
    print('parsed.reqd:', parsed.reqd)

if __name__ == "__main__":
    main()

Bu durum değişmiş olabilir ve çevrimiçi kullanılabilir: command-line.py

Bu koda bir antrenman verecek komut dosyası: command-line-demo.sh


2
Sonunda mantıklı bir argparse örneği
opentokix

5

Ayrıca plac (bir sarmalayıcı argparse) kullanabilirsiniz.

Bonus olarak düzgün yardım talimatları oluşturur - aşağıya bakın.

Örnek komut dosyası:

#!/usr/bin/env python3
def main(
    arg: ('Argument with two possible values', 'positional', None, None, ['A', 'B'])
):
    """General help for application"""
    if arg == 'A':
        print("Argument has value A")
    elif arg == 'B':
        print("Argument has value B")

if __name__ == '__main__':
    import plac
    plac.call(main)

Örnek çıktı:

Argüman sağlanmadı example.py :

usage: example.py [-h] {A,B}
example.py: error: the following arguments are required: arg

Beklenmeyen argüman sağlandı - example.py C :

usage: example.py [-h] {A,B}
example.py: error: argument arg: invalid choice: 'C' (choose from 'A', 'B')

Doğru argüman sağlandı - example.py A :

Argument has value A

Tam yardım menüsü (otomatik olarak oluşturulur) - example.py -h :

usage: example.py [-h] {A,B}

General help for application

positional arguments:
  {A,B}       Argument with two possible values

optional arguments:
  -h, --help  show this help message and exit

Kısa açıklama:

Bağımsız değişkenin adı genellikle parametre adına ( arg) eşittir .

argParametre sonrası grup ek açıklaması şu anlama gelir:

  • Açıklama ( Argument with two possible values)
  • Bağımsız değişken türü - 'bayrak', 'seçenek' veya 'konumsal' ( positional)
  • Kısaltma ( None)
  • Bağımsız değişken değerinin türü - ör. kayan nokta, dize ( None)
  • Sınırlı seçenek kümesi ( ['A', 'B'])

Belgeler:

Plac kullanımı hakkında daha fazla bilgi edinmek için harika belgelerine göz atın :

Plac: Komut Satırını Kolay Yoldan Ayrıştırma


4

Başkalarının söylediklerine eklemek için:

Genellikle bir değişken adı belirtmek için 'dest' parametresini kullanmak ve sonra bu değişkenleri genel ad alanına koymak için 'globals (). Update ()' komutunu kullanmak isterim.

Kullanımı:

$ python script.py -i "Hello, World!"

Kod:

...
parser.add_argument('-i', '--input', ..., dest='inputted_variable',...)
globals().update(vars(parser.parse_args()))
...
print(inputted_variable) # Prints "Hello, World!"

Ad alanında dahili olarak ve değerlerine erişmek için argparsekullanır . Bu şekilde garip bir şekilde oluşturulmuş değerlerden rahatsız olmaz . getattrsetattrdest
hpaulj

1

Kendi kişisel kod yardım talimatlarınızı görüntülemek için argparse'ı kullanmanın ve '-h' / '--help' anahtarlarını değiştirmenin gerçekten basit bir yolu, varsayılan yardımı False olarak ayarlamaktır, ayrıca istediğiniz kadar ek .add_arguments ekleyebilirsiniz. :

import argparse

parser = argparse.ArgumentParser(add_help=False)

parser.add_argument('-h', '--help', action='help',
                help='To run this script please provide two arguments')
parser.parse_args()

Çalıştır: python test.py -h

Çıktı:

usage: test.py [-h]

optional arguments:
  -h, --help  To run this script please provide two arguments

-1

En basit cevap!

PS, argparse belgesini yazan kişi aptalca

python kodu:

import argparse
parser = argparse.ArgumentParser(description='')
parser.add_argument('--o_dct_fname',type=str)
parser.add_argument('--tp',type=str)
parser.add_argument('--new_res_set',type=int)
args = parser.parse_args()
o_dct_fname = args.o_dct_fname
tp = args.tp
new_res_set = args.new_res_set

koşu kodu

python produce_result.py --o_dct_fname o_dct --tp father_child --new_res_set 1

Bu cevap mevcut cevaplardan yeni / farklı bir şey eklemiyor.
NVS Abhilash

Ben
açıkım
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.