Python'da Komut Satırı Argümanları

Genel Bakış

Python'un çok popüler bir programlama dili olmasının yanı sıra çoğu işletim sistemini ve komut satırı argümanı işlemeyi kolaylaştıran birçok kitaplığı desteklemesi nedeniyle, birçok amaç için komut satırı araçları oluşturmak için yaygın olarak kullanılır hale geldi. Bu araçlar, basit CLI uygulamalarından AWS'ler gibi daha karmaşık olanlara kadar değişebilir. Awscli aracı.

Bunun gibi karmaşık araçlar genellikle kullanıcı tarafından komut satırı argümanlarıKullanıcının belirli komutları kullanmasına, seçenekleri ayarlamasına ve daha fazlasına olanak tanır. Örneğin, bu seçenekler araca ek bilgi çıktısı almasını, belirli bir kaynaktan veri okumasını veya çıktıyı belirli bir konuma göndermesini söyleyebilir.

Genel olarak argümanlar, işletim sisteminize bağlı olarak CLI araçlarına farklı şekilde aktarılır:

  • Unix benzeri: - ardından şöyle bir mektup geldi: -hya da -- ardından şöyle bir kelime geliyor: --help
  • Windows: / ardından bir harf veya kelime geliyor /help

Bu farklı yaklaşımlar tarihsel nedenlerden dolayı mevcuttur. Unix benzeri sistemlerdeki birçok program hem tek hem de çift çizgi gösterimini destekler. Tek çizgi gösterimi çoğunlukla tek harfli seçeneklerle kullanılırken, çift çizgi daha okunaklı bir seçenekler listesi sunar; bu, özellikle daha açık olması gereken karmaşık seçenekler için kullanışlıdır.

not: Bu makalede yalnızca Unix benzeri formata odaklanacağız. - ve --.

Bir argümanın hem adının hem de anlamının bir programa özel olduğunu unutmayın; aşağıdaki gibi birkaç genel kural dışında genel bir tanım yoktur. --help Aracın kullanımına ilişkin daha fazla bilgi için. Bir Python betiğinin geliştiricisi olarak, arayan kişiye hangi argümanların sağlanacağına ve onların ne yapacağına siz karar vereceksiniz. Bu, doğru değerlendirmeyi gerektirir.

Kullanılabilir argümanlar listeniz büyüdükçe kodunuz bunları doğru bir şekilde ayrıştırmaya çalışırken daha karmaşık hale gelecektir. Neyse ki Python'da bu konuda size yardımcı olacak çok sayıda kütüphane mevcut. "Kendin yap"tan "kendin yap"a kadar uzanan en yaygın çözümlerden birkaçını ele alacağız. sys.argv, “sizin için yapılır” yaklaşımına argparse.

Python ile Komut Satırı Bağımsız Değişkenlerini Kullanma

Python 3+ ve etrafındaki ekosistem, komut satırı argümanlarını işlemenin bir dizi farklı yolunu destekler. Var çok Komut satırı argümanlarının ayrıştırılmasını kolaylaştıran kütüphaneler.

Yerleşik yol, sys modülü. İsimler ve kullanımı açısından doğrudan C kütüphanesiyle ilgilidir (libc).

İkinci yol ise getopt Parametre değerlerinin değerlendirilmesi dahil, hem kısa hem de uzun seçenekleri işleyen modül.

The argparse modülüden türetilmiş olan optparse modül (Python 2.7'ye kadar mevcuttur).

The docopt olan modül GitHub'da mevcut, aynı işlevselliğe de izin verir.

Son zamanlarda, absl kütüphane aynı zamanda bir değiştirme aracı olarak güç kazanıyor optparse ve getopt().

Bu yolların her birinin artıları ve eksileri vardır; bu nedenle hangisinin ihtiyaçlarınıza en uygun olduğunu görmek için her birini değerlendirmeye değer.

Sistem Modülü

Bu, ilk günlerden beri Python ile birlikte gönderilen temel bir modüldür. C kütüphanesine çok benzer bir yaklaşım gerektirir. argc/argv argümanlara erişmek için. sistem modülü komut satırı argümanlarını adlı basit bir liste yapısında uygular sys.argv.

Her liste öğesi tek bir argümanı temsil eder. Listedeki ilk öğe, sys.argv[0], Python betiğinin adıdır. Liste öğelerinin geri kalanı, sys.argv[1] için sys.argv[n], 2'den n'ye kadar olan komut satırı argümanlarıdır.

Bağımsız değişkenler arasında sınırlayıcı olarak boşluk kullanılır. İçinde boşluk bulunan bağımsız değişken değerlerinin, düzgün bir şekilde ayrıştırılabilmesi için tırnak işaretleri içine alınması gerekir. sys.

eşdeğeri argc yalnızca listedeki öğelerin sayısıdır. Bu değeri elde etmek için Python'u kullanın. len() Şebeke. Bunu daha sonra bir kod örneğinde göstereceğiz.

İlk CLI Bağımsız Değişkenini Yazdırma

Bu ilk örnekte betiğimiz, nasıl çağrıldığını belirleyecek. Bu bilgi, 0 ile indekslenen ilk komut satırı argümanında tutulur. Aşağıdaki kod, Python betiğinizin adını nasıl alacağınızı gösterir:

import sys

print("The script has the name %s" % (sys.argv[0])

Bu kodu adlı bir dosyaya kaydedin. arguments-program-name.pyve ardından aşağıda gösterildiği gibi çağırın. Çıktı aşağıdaki gibidir ve tam yolu da dahil olmak üzere dosya adını içerir:

$ python arguments-program-name.py
The script has the name arguments-program-name.py
$ python /home/user/arguments-program-name.py
The script has the name /home/user/arguments-program-name.py

Yukarıdaki ikinci çağrıda görebileceğiniz gibi, yalnızca Python dosyasının adını değil, aynı zamanda onu çağırmak için kullanılan tam yolu da alıyoruz.

Argüman Sayısını Sayma

Bu ikinci örnekte, yerleşik komut satırını kullanarak komut satırı argümanlarının sayısını sayıyoruz. len() yöntemi. sys.argv incelememiz gereken liste. Aşağıdaki kodda, argüman sayısını alıyoruz ve ardından 1 çıkarıyoruz çünkü bu argümanlardan biri (yani ilki) her zaman dosyanın adı olarak ayarlıdır ve bu bizim için her zaman yararlı değildir. Böylece, kullanıcı tarafından iletilen gerçek argüman sayısı len(sys.argv) - 1:

import sys


arguments = len(sys.argv) - 1
print ("The script is called with %i arguments" % (arguments))

Bu dosyayı argümanlar-count.py olarak kaydedin ve adlandırın. Bu betiği çağırmanın bazı örnekleri aşağıda gösterilmiştir. Buna üç farklı senaryo dahildir:

  • Başka komut satırı argümanı olmayan bir çağrı
  • İki argümanlı bir çağrı
  • İki argümanlı bir çağrı; ikincisi boşluk içeren tırnak içine alınmış bir dizedir
$ python arguments-count.py
The script is called with 0 arguments
$ python arguments-count.py --help me
The script is called with 2 arguments
$ python arguments-count.py --option "long string"
The script is called with 2 arguments
Argümanlar Yoluyla Yineleme

Üçüncü örneğimiz, program adı dışında Python betiğine gönderilen her bağımsız değişkenin çıktısını verir. Bu nedenle, ile başlayan komut satırı argümanları arasında döngü yaparız. ikinci liste öğesi. Python'da listeler 1 tabanlı olduğundan bunun dizin 0 olduğunu hatırlayın:

import sys


arguments = len(sys.argv) - 1


position = 1
while (arguments >= position):
    print ("Parameter %i: %s" % (position, sys.argv[position]))
    position = position + 1

Argümanlar-output.py dosyasına kaydedilen kodumuzu aşağıda çağırıyoruz. Önceki örneğimizde yapıldığı gibi, çıktı üç farklı çağrıyı göstermektedir:

  • Tartışmasız bir çağrı
  • İki argümanlı bir çağrı
  • İkinci argümanın boşluk içeren alıntılanmış bir dize olduğu iki argümanlı bir çağrı
$ python arguments-output.py
$ python arguments-output.py --help me
Parameter 1: --help
Parameter 2: me
$ python arguments-output.py --option "long string"
Parameter 1: --option
Parameter 2: long string

Unutmayın, alıntılanan dize örneğini göstermenin amacı, parametrelerin genellikle bir boşlukla sınırlandırılmasıdır. olmadıkça tırnaklarla çevrilidirler.

Halat Bayrakları (absl)

Abseil'in Bayraklar kütüphanesi, dağıtılmış komut satırı argümanlarıyla komut satırı argümanlarını üretime getirmeyi amaçlamaktadır. Bir modül komut satırı bayraklarını kullandığında ve başka bir modüle (diğer modül) aktarıldığında bayrakları da ithal ediyoruzve bunları içe aktarılan modüle ileterek işleyebilir.

Bu, modüller arasında paylaşılan karmaşık komut satırı argümanlarını daha kolay ve daha az ayrıntılı hale getirir.

Ek olarak kitaplık, bağımsız değişkenlerin varsayılan değerlerini, açıklamalarını ve veri türünü tanımlamanıza olanak tanır; böylece ek denetimler ve dönüştürmeler gerekli olmaz.

from absl import flags
import sys


flags.DEFINE_string('name', 'User', 'The name of the user.')


FLAGS = flags.FLAGS
FLAGS(sys.argv)

print(f"Hello {FLAGS.name}!")

Desteklenen veri türleri şunlardır:

  • DEFINE_integer()
  • DEFINE_string()
  • DEFINE_bool()
  • DEFINE_enum()
  • DEFINE_list()
  • DEFINE_float()

Hem de DEFINE_multi_integer(), DEFINE_multi_string() ve DEFINE_multi_enum() çoklu argüman girişi için. Ek olarak, koşu --help, --helpfullvb. mevcut bayrakları ve açıklamalarını farklı formatlarda yazdırın.

En iyi uygulamalar, endüstri tarafından kabul edilen standartlar ve dahil edilen hile sayfası ile Git'i öğrenmek için uygulamalı, pratik kılavuzumuza göz atın. Googling Git komutlarını durdurun ve aslında öğrenmek o!

Kitaplık aynı zamanda doğrulamaları tanımlamanıza da olanak tanır; hem aralık açısından, hem de tamsayı tabanlı değerler gibi. upper_bound or lower_bound bu kabul edilebilir ve değerleri kontrol etmek için rastgele yöntemler çalıştırmak:

def validate_name(value):
    return len(value) > 15

flags.register_validator('name',
                         validate_name,
                         message='Name is over 15 characters long.',
                         flag_values=FLAGS)

Bunları somut bir örnekte toplayacak olursak:

from absl import flags
import sys

flags.DEFINE_string('name', 'User', 'The name of the user.')
flags.DEFINE_integer('tasks', 0, 'The number of tasks a user has.', lower_bound=0)

FLAGS = flags.FLAGS
FLAGS(sys.argv)

print(f"{FLAGS.name} has {FLAGS.tasks} tasks to work on.")
$ python flags.py --name=John --tasks=5
John has 5 tasks to work on.
$ python flags.py --name=John --tasks=-1

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/absl/flags/_flag.py", line 180, in _parse
    return self.parser.parse(argument)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/absl/flags/_argument_parser.py", line 168, in parse
    raise ValueError('%s is not %s' % (val, self.syntactic_help))
ValueError: -1 is not a non-negative integer
...

argparse Modülü

The argparse modülü Python 3.2'den beri mevcuttur ve optparse Python 2.7'ye kadar mevcut olan modül. Python belgeleri bir API açıklaması ve tüm yöntemleri ayrıntılı olarak kapsayan bir eğitim içerir.

Modül, standartlaştırılmış bir çıktıya sahip bir komut satırı arayüzü sunarken, önceki iki çözüm işin çoğunu sizin ellerinize bırakıyor. argparse Kısa veya uzun stilde ad kontrolüyle sabit ve isteğe bağlı bağımsız değişkenlerin doğrulanmasına olanak tanır. Varsayılan isteğe bağlı bir argüman olarak şunları içerir: -huzun versiyonuyla birlikte --help. Bu argümana, kabul edilen argümanları açıklayan varsayılan bir yardım mesajı eşlik eder.

Aşağıdaki kod, ayrıştırıcının başlatılmasını ve temel çağrıyı ve ardından yardım mesajını gösteren aşağıdaki çıktıyı gösterir. Önceki örneklerde kullandığımız Python çağrılarının aksine, aşağıdaki örneklerde Python 3'ü kullanmayı unutmayın:


import argparse


parser = argparse.ArgumentParser()
parser.parse_args()
$ python3 arguments-argparse-basic.py 
$ python3 arguments-argparse-basic.py -h
usage: arguments-argparse-basic.py [-h]

optional arguments:
  -h, --help  show this help message and exit
$ python3 arguments-argparse-basic.py --verbose
usage: arguments-argparse-basic.py [-h]
arguments-argparse-basic.py: error: unrecognized arguments: --verbose

Bir sonraki adımda kullanıcılarımız için yardım mesajına özel bir açıklama ekleyeceğiz. Ayrıştırıcının bu şekilde başlatılması ek bir metne izin verir. Aşağıdaki kod, açıklamayı text açıkça verilen değişken argparse olarak sınıf description parametre. Aşağıdaki kodu çağırarak çıktının nasıl göründüğünü görebilirsiniz:


import argparse


text = 'This is a test program. It demonstrates how to use the argparse module with a program description.'


parser = argparse.ArgumentParser(description=text)
parser.parse_args()
$ python3 arguments-argparse-description.py --help
usage: arguments-argparse-description.py [-h]

This is a test program. It demonstrates how to use the argparse module with a
program description.

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

Son adım olarak isteğe bağlı bir argüman ekleyeceğiz: -Vadında karşılık gelen uzun stil argümanına sahip olan --version. Bunu yapmak için yöntemi kullanıyoruz add_argument() üç parametreyle çağırdığımız (için görüntülenir) --version, sadece):

  • Parametrenin adı: --version
  • Parametrenin yardım metni: help="show program version"
  • Eylem (ek değer olmadan): action="store_true"

Bunun kaynak kodu aşağıda gösterilmektedir. Argümanları çağrılan değişkene okumak args aracılığıyla yapılır parse_args() yöntemden parser nesne. Tek bir aramada hem kısa hem de uzun versiyonu gönderdiğinizi unutmayın. Son olarak, niteliklerin olup olmadığını kontrol edersiniz. args.V or args.version ayarlandı ve sürüm mesajı çıktı olarak verildi:


import argparse


parser = argparse.ArgumentParser()
parser.add_argument("-V", "--version", help="show program version", action="store_true")


args = parser.parse_args()


if args.version:
    print("This is myprogram version 0.1")
$ python3 arguments-argparse-optional.py -V
This is myprogram version 0.1
$ python3 arguments-argparse-optional.py --version
This is myprogram version 0.1

The --version argümanı komut satırında bir değer verilmesini gerektirmez. Bu yüzden eylem argümanını şu şekilde ayarladık: "store_true". Diğer durumlarda, örneğin belirli bir hacim, yükseklik veya genişlik belirtirseniz, atanmış ek bir değere ihtiyacınız olabilir. Bu, bir sonraki örnekte gösterilmektedir. Varsayılan bir durum olarak lütfen tüm bağımsız değişkenlerin dize olarak yorumlandığını unutmayın:


import argparse


parser = argparse.ArgumentParser()


parser.add_argument("--width", "-w", help="set output width")


args = parser.parse_args()


if args.width:
    print("Set output width to %s" % args.width)

Burada farklı argüman değerleri gönderilirken ne olacağını gösteriyoruz. Bu, hem kısa hem de uzun versiyonun yanı sıra yardım mesajını da içerir:

$ python3 arguments-argparse-optional2.py -w 10
Set output width to 10
$ python3 arguments-argparse-optional2.py --width 10
Set output width to 10
$ python3 arguments-argparse-optional2.py -h
usage: arguments-argparse-optional2.py [-h] [--width WIDTH]

optional arguments:
  -h, --help            show this help message and exit
  --width WIDTH, -w WIDTH
                        set output width

Getopt Modülü

Daha önce fark etmiş olabileceğiniz gibi, sys modül komut satırı dizesini yalnızca tek yönlere böler. Python getopt modülü biraz daha ileri giderek giriş dizesinin ayrılmasını parametre doğrulamayla genişletir. Göre getopt C işlevi, bir değer ataması da dahil olmak üzere hem kısa hem de uzun seçeneklere izin verir.

Uygulamada, aşağıdakileri gerektirir: sys Giriş verilerini düzgün bir şekilde işlemek için modül. Bunu yapmak için hem sys modülü ve getopt modülün önceden yüklenmesi gerekir. Daha sonra, giriş parametreleri listesinden ilk liste öğesini kaldırıyoruz (aşağıdaki koda bakın) ve komut satırı argümanlarının geri kalan listesini adı verilen değişkende saklıyoruz. argument_list:


import getopt, sys


full_cmd_arguments = sys.argv


argument_list = full_cmd_arguments[1:]

print argument_list

argümanlar argument_list artık kullanılarak ayrıştırılabilir getopts() yöntem. Ama bunu yapmadan önce şunu söylememiz gerekiyor. getopts() hangi parametrelerin geçerli olduğu hakkında. Bunlar şu şekilde tanımlanır:

short_options = "ho:v"
long_options = ["help", "output=", "verbose"]

Bu, bu argümanların bazı ekstra bilgilerle birlikte geçerli olduğunu düşündüğümüz argümanlar olduğu anlamına gelir:

------------------------------------------
long argument   short argument  with value
------------------------------------------
--help           -h              no
--output         -o              yes
--verbose        -v              no
------------------------------------------

fark etmiş olabilirsiniz o kısa seçenek iki nokta üst üste ile devam etti, :. Bu söyler getopt bu seçeneğe bir değer atanması gerekir.

Bu artık bir argüman listesini işlememize izin veriyor. getopt() yöntemin yapılandırılması için üç parametre gerekir - gerçek bağımsız değişkenlerin listesi argv, ayrıca geçerli kısa ve uzun seçeneklerin yanı sıra (önceki kod parçacığında gösterilmiştir).

Yöntem çağrısının kendisi, değerlendirme sırasındaki hataları kapsamak için bir try-catch-ifadesinde tutulur. Daha önce tanımlandığı gibi listenin parçası olmayan bir bağımsız değişken keşfedilirse bir istisna ortaya çıkar. Python betiği hata mesajını ekrana yazdıracak ve hata kodu 2 ile çıkacaktır:

try:
    arguments, values = getopt.getopt(argument_list, short_options, long_options)
except getopt.error as err:
    
    print (str(err))
    sys.exit(2)

Son olarak, karşılık gelen değerlere sahip argümanlar, adı geçen iki değişkende saklanır. arguments ve values. Artık bu değişkenleri kodunuzda kolayca değerlendirebilirsiniz. Bir tane kullanabiliriz for-loop, tanınan argümanlar listesinde bir girişten diğerine geçmek için.


for current_argument, current_value in arguments:
    if current_argument in ("-v", "--verbose"):
        print ("Enabling verbose mode")
    elif current_argument in ("-h", "--help"):
        print ("Displaying help")
    elif current_argument in ("-o", "--output"):
        print (("Enabling special output mode (%s)") % (current_value))

Aşağıda bu kodun çalıştırılmasının çıktısını görebilirsiniz. Programın hem geçerli hem de geçersiz program argümanlarına nasıl tepki verdiğini göstereceğiz:

$ python arguments-getopt.py -h
Displaying help
$ python arguments-getopt.py --help
Displaying help
$ python arguments-getopt.py --output=green --help -v
Enabling special output mode (green)
Displaying help
Enabling verbose mode
$ python arguments-getopt.py -verbose
option -e not recognized

Programımıza yapılan son çağrı ilk başta biraz kafa karıştırıcı görünebilir. Bunu anlamak için kısa yol seçeneklerinin (bazen bayrak olarak da adlandırılır) tek bir çizgi ile birlikte kullanılabileceğini bilmeniz gerekir. Bu, aracınızın birçok seçeneği daha kolay kabul etmesini sağlar. Örneğin, aramak python arguments-getopt.py -vh aramakla aynı şey python arguments-getopt.py -v -h. Yani yukarıdaki son çağrıda, getopt modül kullanıcının geçmeye çalıştığını düşündü -e geçersiz bir seçenek olarak.

Sonuç

Bu makalede Python'da komut satırı argümanlarını almak için birçok farklı yöntem gösterdik. sys, getopt, ve argparse. Bu modüllerin işlevleri farklılık gösterir; bazıları diğerlerinden çok daha fazlasını sağlar. sys tamamen esnektir, oysa her ikisi de getoptve argparse bir yapı gerektirir. Buna karşılık, karmaşık işlerin çoğunu kapsıyorlar. sys size kalıyor. Verilen örnekleri inceledikten sonra hangi modülün projenize en uygun olduğunu belirleyebilmelisiniz.

Bu yazıda aşağıdaki gibi diğer çözümlerden bahsetmedik. docopts modül, az önce bahsetmiştik. Bu modül tamamen farklı bir yaklaşım izlemektedir ve sonraki makalelerden birinde ayrıntılı olarak açıklanacaktır.

Referanslar

Zaman Damgası:

Den fazla Yığın kötüye kullanımı