Mostanság parancssori scripteket írogatok Python-ban, ha éppen nincs jobb dolgom (ritka). Gondoltam hát, hogy ezzel kapcsolatos tapasztalataimat és a nyelvvel való ismerkedésemet megosztom egy - egyelőre még nem tudni hány részes - bejegyzéssorozatban. Az első rész témája az alkalmazásnak átadott paraméterek feldolgozása a getopt és az optparse modulok segítségével.

A programunk egy egyszerű "Hello World!" alkalmazás lesz parancssori stílusban. Két fajta bemenő paramétert fogad el. Az egyik a név, akinek köszönni fog, a másikra pedig megjeleníti a súgót, hogy hogyan is kell paraméterezni ezt a rettentő bonyolult programot.

A getopt

A legkézenfekvőbb módszer a paraméterek feldolgozására a getopt modul getopt() függvénye. Szükségünk lesz ezen kívül még a sys modulra, hogy a feldolgozandó lista is a birtokunkba kerüljön (mellesleg a getopt() függvény PHP-ban is létezik):

from getopt import getopt, GetoptError
import sys

A feldolgozás során a getopt() egy GetoptError kivételt dob, ha nem talál rendben valamit. A függvény első paramétere a bemenő adatok tömbje (az első indextől, mivel a nulladik index az a meghívott fájl neve), a második paraméter a rövid kapcsolók listája (kettőspont van a betűk mögött, amik paramétert várnak), a harmadik paraméter pedig a hosszú kapcsolók listája (egyenlőségjellel a név mögött, ha paramétert várnak). A visszatérési értéke két tömb, az első paraméternév-érték párokat tartalmaz, a második pedig a fel nem dolgozott parancssori argumentumokat.

try:
    opts, args = getopt(sys.argv[1:], 'hn:', ['help', 'name='])
except GetoptError:
    print 'Parameterezesi hiba'
    sys.exit(1)

Ha nem szállt el a program hibával, akkor megadjuk a változóinknak (jelen esetben csak a name-nek) az alapértelmezett értékeket és végigmegyünk az opts tömbön, hogy feltölthessük őket valós adatokkal.

name = False

for opt, arg in opts:
    if opt in ('-h', '--help'):
        print 'usage: %s --name=NAME' % sys.argv[0]
        sys.exit(0)
    elif opt in ('-n', '--name'):
        name = arg

Nem maradt más hátra, mint a name változó ellenőrzése és siker esetén a köszöntés kiiratása:

if not name:
    print 'Add meg a nevet!'
    sys.exit(2)

print 'Hello, ' + name + '!'

Ha a name változó kezdőértéke például 'World' lenne, akkor a feldolgozás utáni ellenőrzést el is hagyhatnánk és a programunk működése úgy módosulna, hogy a világot köszöntené, ha nem kap más paramétert.

Az optparse

A Python 2.3-as verziója óta rendelkezésre áll az optparse modul is, ami még egy pár gondot levesz a vállunkról méghozzá objektum-orientált módon. Ez esetben a sys modulra nem lesz szükségünk, a parancssori paraméterek begyűjtését az optparse végzi.

from optparse import OptionParser

Beállítjuk, hogy milyen paramétereket várunk és azt is, hogy mik lesznek ezeknek az alapértelmezett értékei. Ezek után feldolgozzuk a bejövő adatokat.

parser = OptionParser()
parser.add_option(
    '-n', '--name',
    dest = 'name',
    help = 'a koszontendo neve',
    metavar = 'NAME'
)
parser.set_defaults(name = False)
opts, args = parser.parse_args()

Ami azonnal feltűnhet, hogy a -h és --help kapcsolókat nem adtuk meg. Ezt az optparser automatikusan megteszi és még a segítség szövegét is legenerálja nekünk (az add_option() help és metavar paramétere alapján). A feldolgozás után kapott értékeket az opts tömbben érjük el az add_option()-nak megadott dest paraméter nevű kulcsként.

if not opts.name:
    parser.error('Add meg a nevet!')

print 'Hello ' + opts.name + '!'

Ezzel meg is lennénk. Nem tűnik sokkal rövidebbnek a kód, de több paraméter esetén szembetűnőbb lenne a getopt esetén a kód közepén az a hatalmas if-elif erdő. Ezen kívül ugye egy elég szép súgó kimenetet generál nekünk és bizonyos fokig kezeli a hibákat is (üres paraméter, nem numerikus paraméter - ha az van beállítva) egy kulturált hibakimenetet mutatva.

Példafájlok

A következő részben előreláthatólag különböző konfigurációs fájlok feldolgozásának módjáról lesz szó. Addig is kellemes paraméterezést.