Как мога да обработя аргументи на командния ред в Python?

Какъв би бил лесен израз за обработка на аргументи от командния ред, ако очаквам нещо като 001 или 999 (нека ограничим очакванията до диапазона 001...999 за този път) и няколко други предадени аргумента и бих искал да игнорирам всички неочаквани ?

Разбирам, че ако например трябва да разбера дали "debug" е предадено сред параметрите, ще бъде нещо подобно:

if 'debug' in argv[1:]:
  print 'Will be running in debug mode.'

Как да разбера дали 009 или 575 е преминал?

Всички тези са очаквани обаждания:

python script.py
python script.py 011
python script.py 256 debug
python script.py 391 xls
python script.py 999 debug pdf

На този етап не ми пука за обаждания като това:

python script.py 001 002 245 568
python script.py some unexpected argument
python script.py 0001
python script.py 02

...първият - поради повече от един "числов" аргумент; второ - заради... ами неочаквани спорове; трети и четвърти - поради нетрицифрени аргументи.


person user63503    schedule 20.02.2009    source източник
comment
вижте това stackoverflow.com/questions/25605380/   -  person geekyjazzy    schedule 01.09.2014


Отговори (5)


Както други отговориха, optparse е най-добрият вариант, но ако просто искате бърз код, опитайте нещо подобно:

import sys, re

first_re = re.compile(r'^\d{3}$')

if len(sys.argv) > 1:

    if first_re.match(sys.argv[1]):
        print "Primary argument is : ", sys.argv[1]
    else:
        raise ValueError("First argument should be ...")

    args = sys.argv[2:]

else:

    args = ()

# ... anywhere in code ...

if 'debug' in args:
    print 'debug flag'

if 'xls' in args:
    print 'xls flag'

РЕДАКТИРАНЕ: Ето пример за optparse, защото толкова много хора отговарят на optparse, без наистина да обяснят защо или да обяснят какво трябва да промените, за да работи.

Основната причина да използвате optparse е, че ви дава повече гъвкавост за разширяване по-късно и ви дава повече гъвкавост на командния ред. С други думи, вашите опции могат да се показват в произволен ред и съобщенията за използване се генерират автоматично. Въпреки това, за да работи с optparse, трябва да промените спецификациите си, за да поставите '-' или '--' пред незадължителните аргументи и трябва да позволите на всички аргументи да бъдат в произволен ред.

Ето един пример за използване на optparse:

import sys, re, optparse

first_re = re.compile(r'^\d{3}$')

parser = optparse.OptionParser()
parser.set_defaults(debug=False,xls=False)
parser.add_option('--debug', action='store_true', dest='debug')
parser.add_option('--xls', action='store_true', dest='xls')
(options, args) = parser.parse_args()

if len(args) == 1:
    if first_re.match(args[0]):
        print "Primary argument is : ", args[0]
    else:
        raise ValueError("First argument should be ...")
elif len(args) > 1:
    raise ValueError("Too many command line arguments")

if options.debug:
    print 'debug flag'

if options.xls:
    print 'xls flag'

Разликите тук с optparse и вашите спецификации са, че сега можете да имате командни редове като:

python script.py --debug --xls 001

и можете лесно да добавяте нови опции, като извикате parser.add_option()

person Van Gale    schedule 20.02.2009
comment
но имайте предвид: optparse е отхвърлен от [Python] версия 2.7: Модулът optparse е отхвърлен и няма да бъде разработван по-нататък; разработката ще продължи с модула argparse. Вижте: docs.python.org/2/library/optparse.html - person kkurian; 11.02.2014

Разгледайте модула optparse. Справянето с sys.argv сами е добре за наистина прости неща, но бързо излиза извън контрол.

Обърнете внимание, че може да намерите optparse за по-лесен за използване, ако можете да промените малко формата на вашия аргумент; напр. заменете debug с --debug и xls с --xls или --output=xls.

person John Fouhy    schedule 20.02.2009
comment
Не съм сигурен, че това си струва, когато OP използва просто аргументи, а не опции. - person Nikhil Chelliah; 20.02.2009
comment
Имайте предвид, че optparse е заменен с argparse - person Skip Huffman; 17.10.2011

optparse е най-добрият ви приятел за анализиране на командния ред. Също така разгледайте argparse; не е в стандартната библиотека обаче.

person regan    schedule 20.02.2009
comment
Точно като бележка argparse вече е стандарт в Python 2.7 и дори изглежда има е пренесен към 2.6.8. Според документацията на optparse, optparse вече е отхвърлен. - person Trebor Rude; 03.04.2013

Ако искате да приложите действителни превключватели на командния ред, разгледайте getopt. Освен това е невероятно лесен за използване.

person Community    schedule 20.02.2009
comment
Не бих казал, че getopt е толкова прост - разбира се, по-добре е, отколкото да правите анализирането ръчно, но това е просто порт на някакъв C код, който всъщност не се възползва от силните страни на Python. Почти винаги препоръчвам optparse вместо getopt. - person David Z; 20.02.2009

Ван Гейл е до голяма степен прав в използването на регулярния израз срещу аргумента. Въпреки това, НЕ е абсолютно необходимо да направите всичко опция, когато използвате optparse, който разделя sys.argv на опции и аргументи, въз основа на това дали "-" или "--" е отпред или не. Примерен код за преминаване само през аргументите:

import sys
import optparse

claParser = optparse.OptionParser()
claParser.add_option(
(opts, args) = claParser.parse_args()
if (len(args) >= 1):
  print "Arguments:"
  for arg in args:
    print "  " + arg
else:
  print "No arguments"
sys.exit(0)

Да, масивът args се анализира почти по същия начин като sys.argv, но е добавена възможност за лесно добавяне на опции, ако е необходимо. За повече информация относно optparse вижте съответния документ за Python.

person PTBNL    schedule 20.02.2009