Yanıtlar:
Bu cevap, optparse
eski Python sürümleri için hangisinin uygun olduğunu göstermektedir . Python 2.7 ve üstü için yer argparse
değiştirir optparse
. Daha fazla bilgi için bu cevaba bakınız .
Diğer insanların işaret ettiği gibi, getopt üzerinde optparse ile gitmek daha iyidir. getopt, standart getopt (3) C kütüphanesi işlevlerinin neredeyse bire bir eşleşmesidir ve kullanımı çok kolay değildir.
optparse, biraz daha ayrıntılı olsa da, daha iyi yapılandırılmış ve daha sonra genişletilmesi daha kolaydır.
Ayrıştırıcıya bir seçenek eklemek için tipik bir satır:
parser.add_option('-q', '--query',
action="store", dest="query",
help="query string", default="spam")
Kendisi için hemen hemen konuşur; işlem zamanında -q veya --query seçeneklerini seçenek olarak kabul eder, bağımsız değişkeni sorgu adı verilen bir öznitelikte saklar ve belirtmezseniz varsayılan bir değere sahiptir. Ayrıca, seçenekle birlikte (-h / - help ile çalıştırıldığında kullanılacak) yardım argümanını bildirmeniz de kendi kendini belgelemektedir.
Genellikle argümanlarınızı aşağıdakilerle ayrıştırırsınız:
options, args = parser.parse_args()
Bu, varsayılan olarak, komut dosyasına geçirilen standart bağımsız değişkenleri ayrıştırır (sys.argv [1:])
options.query daha sonra komut dosyasına geçirdiğiniz değere ayarlanır.
Basitçe yaparak bir ayrıştırıcı oluşturursunuz
parser = optparse.OptionParser()
Bunların hepsi ihtiyacınız olan temel bilgilerdir. İşte bunu gösteren eksiksiz bir Python betiği:
import optparse
parser = optparse.OptionParser()
parser.add_option('-q', '--query',
action="store", dest="query",
help="query string", default="spam")
options, args = parser.parse_args()
print 'Query string:', options.query
Temel bilgileri gösteren 5 satır python.
Sample.py dosyasına kaydedin ve bir kez çalıştırın.
python sample.py
ve bir kere
python sample.py --query myquery
Bunun ötesinde, optparse'ın uzatılmasının çok kolay olduğunu göreceksiniz. Projelerimden birinde, alt komutları bir komut ağacına kolayca yerleştirmenizi sağlayan bir Komut sınıfı oluşturdum. Komutları birbirine zincirlemek için ağırlıklı olarak optparse kullanır. Birkaç satırda kolayca açıklayabileceğim bir şey değil, ancak ana sınıf depomun yanı sıra onu ve seçenek ayrıştırıcısını kullanan bir sınıfta dolaşmaktan çekinmeyin
-mcProfile -o program.prof
ancak agrparcer bu argümanları yakalıyor, bu argümanları python exe'ye nasıl geçirebilirim ???
argparse
gitmek için bir yoldur. İşte nasıl kullanılacağına dair kısa bir özet:
1) Başlat
import argparse
# Instantiate the parser
parser = argparse.ArgumentParser(description='Optional app description')
2) Bağımsız Değişken Ekle
# Required positional argument
parser.add_argument('pos_arg', type=int,
help='A required integer positional argument')
# Optional positional argument
parser.add_argument('opt_pos_arg', type=int, nargs='?',
help='An optional integer positional argument')
# Optional argument
parser.add_argument('--opt_arg', type=int,
help='An optional integer argument')
# Switch
parser.add_argument('--switch', action='store_true',
help='A boolean switch')
3) Ayrıştırma
args = parser.parse_args()
4) Erişim
print("Argument values:")
print(args.pos_arg)
print(args.opt_pos_arg)
print(args.opt_arg)
print(args.switch)
5) Değerleri Kontrol Edin
if args.pos_arg > 10:
parser.error("pos_arg cannot be larger than 10")
Doğru kullanım:
$ ./app 1 2 --opt_arg 3 --switch
Argument values:
1
2
3
True
Yanlış argümanlar:
$ ./app foo 2 --opt_arg 3 --switch
usage: convert [-h] [--opt_arg OPT_ARG] [--switch] pos_arg [opt_pos_arg]
app: error: argument pos_arg: invalid int value: 'foo'
$ ./app 11 2 --opt_arg 3
Argument values:
11
2
3
False
usage: app [-h] [--opt_arg OPT_ARG] [--switch] pos_arg [opt_pos_arg]
convert: error: pos_arg cannot be larger than 10
Tam yardım:
$ ./app -h
usage: app [-h] [--opt_arg OPT_ARG] [--switch] pos_arg [opt_pos_arg]
Optional app description
positional arguments:
pos_arg A required integer positional argument
opt_pos_arg An optional integer positional argument
optional arguments:
-h, --help show this help message and exit
--opt_arg OPT_ARG An optional integer argument
--switch A boolean switch
2012'den beri docopt adı verilen argüman ayrıştırma için çok kolay, güçlü ve gerçekten harika bir modül var . Dokümanlarından alınan bir örnek:
"""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)
Budur Yani: 2 kod satırını artı doc dize olan esansiyel ve aldığınız senin argümanlar çözümlenir ve argümanlar nesne mevcut.
2017'den beri python-fire adlı başka bir serin modül var . Sıfır argüman ayrıştırma yaparken kodunuz için bir CLI arayüzü oluşturabilir . Belgelerden basit bir örnek (bu küçük program işlevi double
komut satırına gösterir):
import fire
class Calculator(object):
def double(self, number):
return 2 * number
if __name__ == '__main__':
fire.Fire(Calculator)
Komut satırından şunları çalıştırabilirsiniz:
> calculator.py double 10
20
> calculator.py double --number=15
30
Yeni kalça yoludur argparse
için bu nedenlerden. argparse> optparse> getopt
update: py2.7'den itibaren argparse standart kütüphanenin bir parçasıdır ve optparse kullanımdan kaldırılmıştır.
Ben tercih tıklayın . Yönetim seçeneklerini özetler ve "(...) gerektiği kadar az kodla güzel bir komut satırı arabirimleri oluşturulabilir bir şekilde oluşturmaya izin verir".
İşte örnek kullanım:
import click
@click.command()
@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name',
help='The person to greet.')
def hello(count, name):
"""Simple program that greets NAME for a total of COUNT times."""
for x in range(count):
click.echo('Hello %s!' % name)
if __name__ == '__main__':
hello()
Ayrıca otomatik olarak güzel biçimlendirilmiş yardım sayfaları oluşturur:
$ python hello.py --help
Usage: hello.py [OPTIONS]
Simple program that greets NAME for a total of COUNT times.
Options:
--count INTEGER Number of greetings.
--name TEXT The person to greet.
--help Show this message and exit.
Hemen hemen herkes getopt kullanıyor
İşte doc için örnek kod:
import getopt, sys
def main():
try:
opts, args = getopt.getopt(sys.argv[1:], "ho:v", ["help", "output="])
except getopt.GetoptError:
# print help information and exit:
usage()
sys.exit(2)
output = None
verbose = False
for o, a in opts:
if o == "-v":
verbose = True
if o in ("-h", "--help"):
usage()
sys.exit()
if o in ("-o", "--output"):
output = a
Kısacası, işte böyle.
İki tür seçeneğiniz var. Argüman alan ve anahtar gibi olanlar.
sys.argv
Hemen hemen edilir char** argv
C. Like Programınıza ve ayrıştırmanın o sadece argümanlar adıdır ilk elemanını atlamak C:sys.argv[1:]
Getopt.getopt
argümanda verdiğiniz kurala göre ayrıştırır.
"ho:v"
Burada kısa argümanları anlatır: -ONELETTER
. Bir argümanı kabul eden :
araçlar -o
.
Son ["help", "output="]
olarak uzun argümanlar ( --MORETHANONELETTER
) açıklanmaktadır . =
Sonra çıktı bir kez daha bu çıkış bir argüman kabul anlamına gelir.
Sonuç, çiftin bir listesidir (seçenek, bağımsız değişken)
Bir seçenek ( --help
burada arg
olduğu gibi ) herhangi bir argümanı kabul etmezse , bölüm boş bir dizedir. Daha sonra genellikle bu listede döngü yapmak ve örnekte olduğu gibi seçenek adını test etmek istersiniz.
Umarım bu sana yardımcı olmuştur.
getopt
Python'un daha yeni sürümlerinde kullanımdan kaldırıldığında bu cevap güncelliğini yitirdi.
getopt
hala kullanımdan kaldırılmamıştır… Ancak belgelerinde esas olarak C getopt()
işlevini bilen kullanıcılar için sağlandığını ve diğer kullanıcılar argparse
için daha az kod yazıp msgstr "daha iyi yardım ve hata mesajları" #:.
optparse
Standart kitaplık ile birlikte gelen kullanımı . Örneğin:
#!/usr/bin/env python
import optparse
def main():
p = optparse.OptionParser()
p.add_option('--person', '-p', default="world")
options, arguments = p.parse_args()
print 'Hello %s' % options.person
if __name__ == '__main__':
main()
Kaynak: UNIX komut satırı araçları oluşturmak için Python kullanma
Ancak Python 2.7 optparse kullanımdan kaldırılmıştır, bakınız: Optparse yerine neden argparse kullanılır?
Her ihtimale karşı size gerekiyorsa, bu yardımcı olabilir gerekebilir kapmak Win32 üzerinde unicode argümanlar (2K, XP vs):
from ctypes import *
def wmain(argc, argv):
print argc
for i in argv:
print i
return 0
def startup():
size = c_int()
ptr = windll.shell32.CommandLineToArgvW(windll.kernel32.GetCommandLineW(), byref(size))
ref = c_wchar_p * size.value
raw = ref.from_address(ptr)
args = [arg for arg in raw]
windll.kernel32.LocalFree(ptr)
exit(wmain(len(args), args))
startup()
Hafif komut satırı bağımsız değişkeni varsayılanları
Her ne kadar argparse
harika ve tam olarak belgelenmiş komut satırı anahtarları ve gelişmiş özellikler için doğru yanıt olsa da , basit konumsal bağımsız değişkenleri çok basit bir şekilde işlemek için işlev bağımsız değişkeni kullanabilirsiniz.
import sys
def get_args(name='default', first='a', second=2):
return first, int(second)
first, second = get_args(*sys.argv)
print first, second
'Name' argümanı kod adını yakalar ve kullanılmaz. Test çıktısı şöyle görünür:
> ./test.py
a 2
> ./test.py A
A 2
> ./test.py A 20
A 20
Bazı varsayılan değerleri istediğim basit komut dosyaları için bunu oldukça yeterli buluyorum. Ayrıca, dönüş değerlerine bir tür baskı eklemek isteyebilirsiniz, aksi takdirde komut satırı değerlerinin tümü dize olur.
Ben getopt tercih optparse. Bu çok bildirim niteliğindedir: Ona seçeneklerin adlarını ve sahip olmaları gereken etkileri söylersiniz (örneğin, bir boolean alanı ayarlamak) ve size belirttiğiniz özelliklere göre doldurulmuş bir sözlüğü geri verir.
Bence daha büyük projeler için en iyi yol tercih etmek, ancak kolay bir yol arıyorsanız, belki http://werkzeug.pocoo.org/documentation/script sizin için bir şeydir.
from werkzeug import script
# actions go here
def action_foo(name=""):
"""action foo does foo"""
pass
def action_bar(id=0, title="default title"):
"""action bar does bar"""
pass
if __name__ == '__main__':
script.run()
Temelde her action_ * işlevi komut satırına maruz kalır ve ücretsiz olarak güzel bir yardım mesajı oluşturulur.
python foo.py
usage: foo.py <action> [<options>]
foo.py --help
actions:
bar:
action bar does bar
--id integer 0
--title string default title
foo:
action foo does foo
--name string
declarative_parser
. Tabii ki, biri werkzeug ile çalışıyorsa, tutmak daha iyi olabilir werkzung.script
. Her neyse, bu yaklaşımın büyük bir hayranıyım.
Argparse kodu gerçek uygulama kodundan daha uzun olabilir!
En popüler argüman ayrıştırma seçeneklerinde bulduğum bir sorun, parametreleriniz mütevazı ise, bunları belgeleyen kodun sağladığı faydaya göre orantısız olarak büyük olmasıdır.
Tartışmayı çözümleme sahnesine göreceli yeni gelen (sanırım) plas .
Argparse ile bazı onaylanmış ödünleşmeler yapar, ancak satır içi belgeleri kullanır ve yalnızca main()
tür işlev işlevi etrafına sarar :
def main(excel_file_path: "Path to input training file.",
excel_sheet_name:"Name of the excel sheet containing training data including columns 'Label' and 'Description'.",
existing_model_path: "Path to an existing model to refine."=None,
batch_size_start: "The smallest size of any minibatch."=10.,
batch_size_stop: "The largest size of any minibatch."=250.,
batch_size_step: "The step for increase in minibatch size."=1.002,
batch_test_steps: "Flag. If True, show minibatch steps."=False):
"Train a Spacy (http://spacy.io/) text classification model with gold document and label data until the model nears convergence (LOSS < 0.5)."
pass # Implementation code goes here!
if __name__ == '__main__':
import plac; plac.call(main)
consoleargs burada belirtilmeyi hak ediyor. Kullanımı çok kolaydır. Bunu kontrol et:
from consoleargs import command
@command
def main(url, name=None):
"""
:param url: Remote URL
:param name: File name
"""
print """Downloading url '%r' into file '%r'""" % (url, name)
if __name__ == '__main__':
main()
Şimdi konsolda:
% python demo.py --help
Usage: demo.py URL [OPTIONS]
URL: Remote URL
Options:
--name -n File name
% python demo.py http://www.google.com/
Downloading url ''http://www.google.com/'' into file 'None'
% python demo.py http://www.google.com/ --name=index.html
Downloading url ''http://www.google.com/'' into file ''index.html''
İşte benim için işe yarayan bir kütüphane değil, bir yöntem.
Buradaki hedefler ters, her bir argüman tek bir satırla ayrıştırılır, argümanlar okunabilirlik için sıralanır, kod basittir ve herhangi bir özel modüle (sadece os + sys) bağlı değildir, eksik veya bilinmeyen argümanları incelikle uyarır , / range () döngüsü için basit kullanın ve python 2.x ve 3.x üzerinde çalışır
Gösterilen iki geçiş bayrağı (-d, -v) ve bağımsız değişkenler (-i xxx ve -o xxx) tarafından kontrol edilen iki değerdir.
import os,sys
def HelpAndExit():
print("<<your help output goes here>>")
sys.exit(1)
def Fatal(msg):
sys.stderr.write("%s: %s\n" % (os.path.basename(sys.argv[0]), msg))
sys.exit(1)
def NextArg(i):
'''Return the next command line argument (if there is one)'''
if ((i+1) >= len(sys.argv)):
Fatal("'%s' expected an argument" % sys.argv[i])
return(1, sys.argv[i+1])
### MAIN
if __name__=='__main__':
verbose = 0
debug = 0
infile = "infile"
outfile = "outfile"
# Parse command line
skip = 0
for i in range(1, len(sys.argv)):
if not skip:
if sys.argv[i][:2] == "-d": debug ^= 1
elif sys.argv[i][:2] == "-v": verbose ^= 1
elif sys.argv[i][:2] == "-i": (skip,infile) = NextArg(i)
elif sys.argv[i][:2] == "-o": (skip,outfile) = NextArg(i)
elif sys.argv[i][:2] == "-h": HelpAndExit()
elif sys.argv[i][:1] == "-": Fatal("'%s' unknown argument" % sys.argv[i])
else: Fatal("'%s' unexpected" % sys.argv[i])
else: skip = 0
print("%d,%d,%s,%s" % (debug,verbose,infile,outfile))
NextArg () öğesinin amacı, eksik verileri kontrol ederken bir sonraki bağımsız değişkeni döndürmektir ve NextArg () kullanıldığında 'atla' döngüsü atlayarak bir satırı aşağıya ayrıştırır.
Erco'nun gerekli konumsal argümanlara ve isteğe bağlı argümanlara izin verme yaklaşımını genişlettim. Bunlar -d, -v vb argümanlarından önce gelmelidir.
Konumsal ve isteğe bağlı bağımsız değişkenler, sırasıyla PosArg (i) ve OptArg (i, varsayılan) ile alınabilir. İsteğe bağlı bir argüman bulunduğunda, seçeneklerin (ör. -İ) aranmasının başlangıç konumu, 'beklenmedik' bir ölümcül oluşmasını önlemek için 1 ileri hareket ettirilir.
import os,sys
def HelpAndExit():
print("<<your help output goes here>>")
sys.exit(1)
def Fatal(msg):
sys.stderr.write("%s: %s\n" % (os.path.basename(sys.argv[0]), msg))
sys.exit(1)
def NextArg(i):
'''Return the next command line argument (if there is one)'''
if ((i+1) >= len(sys.argv)):
Fatal("'%s' expected an argument" % sys.argv[i])
return(1, sys.argv[i+1])
def PosArg(i):
'''Return positional argument'''
if i >= len(sys.argv):
Fatal("'%s' expected an argument" % sys.argv[i])
return sys.argv[i]
def OptArg(i, default):
'''Return optional argument (if there is one)'''
if i >= len(sys.argv):
Fatal("'%s' expected an argument" % sys.argv[i])
if sys.argv[i][:1] != '-':
return True, sys.argv[i]
else:
return False, default
### MAIN
if __name__=='__main__':
verbose = 0
debug = 0
infile = "infile"
outfile = "outfile"
options_start = 3
# --- Parse two positional parameters ---
n1 = int(PosArg(1))
n2 = int(PosArg(2))
# --- Parse an optional parameters ---
present, a3 = OptArg(3,50)
n3 = int(a3)
options_start += int(present)
# --- Parse rest of command line ---
skip = 0
for i in range(options_start, len(sys.argv)):
if not skip:
if sys.argv[i][:2] == "-d": debug ^= 1
elif sys.argv[i][:2] == "-v": verbose ^= 1
elif sys.argv[i][:2] == "-i": (skip,infile) = NextArg(i)
elif sys.argv[i][:2] == "-o": (skip,outfile) = NextArg(i)
elif sys.argv[i][:2] == "-h": HelpAndExit()
elif sys.argv[i][:1] == "-": Fatal("'%s' unknown argument" % sys.argv[i])
else: Fatal("'%s' unexpected" % sys.argv[i])
else: skip = 0
print("Number 1 = %d" % n1)
print("Number 2 = %d" % n2)
print("Number 3 = %d" % n3)
print("Debug = %d" % debug)
print("verbose = %d" % verbose)
print("infile = %s" % infile)
print("outfile = %s" % outfile)