Python Language
Разбор аргументов командной строки
Поиск…
Вступление
Большинство инструментов командной строки полагаются на аргументы, переданные программе после ее выполнения. Вместо запроса ввода данных эти программы ожидают, что данные или определенные флаги (которые становятся логическими) будут установлены. Это позволяет как пользовательским, так и другим программам запускать файл Python, передавая его по мере его запуска. В этом разделе объясняется и демонстрируется реализация и использование аргументов командной строки в Python.
Привет, мир в argparse
Следующая программа приветствует пользователя. Он принимает один позиционный аргумент, имя пользователя и также может быть передан приветствие.
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('name',
help='name of user'
)
parser.add_argument('-g', '--greeting',
default='Hello',
help='optional alternate greeting'
)
args = parser.parse_args()
print("{greeting}, {name}!".format(
greeting=args.greeting,
name=args.name)
)
$ python hello.py --help
usage: hello.py [-h] [-g GREETING] name
positional arguments:
name name of user
optional arguments:
-h, --help show this help message and exit
-g GREETING, --greeting GREETING
optional alternate greeting
$ python hello.py world
Hello, world!
$ python hello.py John -g Howdy
Howdy, John!
Для получения дополнительной информации, пожалуйста, прочитайте документацию argparse .
Основной пример с docopt
docopt преобразует аргумент аргумента командной строки на голове. Вместо анализа аргументов вы просто пишете строку использования для своей программы, а docopt анализирует строку использования и использует ее для извлечения аргументов командной строки.
"""
Usage:
script_name.py [-a] [-b] <path>
Options:
-a Print all the things.
-b Get more bees into the path.
"""
from docopt import docopt
if __name__ == "__main__":
args = docopt(__doc__)
import pprint; pprint.pprint(args)
Примеры прогонов:
$ python script_name.py
Usage:
script_name.py [-a] [-b] <path>
$ python script_name.py something
{'-a': False,
'-b': False,
'<path>': 'something'}
$ python script_name.py something -a
{'-a': True,
'-b': False,
'<path>': 'something'}
$ python script_name.py -b something -a
{'-a': True,
'-b': True,
'<path>': 'something'}
Установка взаимно исключающих аргументов с помощью argparse
Если вы хотите, чтобы два или более аргумента были взаимоисключающими. Вы можете использовать функцию argparse.ArgumentParser.add_mutually_exclusive_group()
. В приведенном ниже примере может существовать либо foo, либо bar, но не оба одновременно.
import argparse
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument("-f", "--foo")
group.add_argument("-b", "--bar")
args = parser.parse_args()
print "foo = ", args.foo
print "bar = ", args.bar
Если вы попытаетесь запустить скрипт, указав оба аргумента --foo
и --bar
, скрипт будет жаловаться на следующее сообщение.
error: argument -b/--bar: not allowed with argument -f/--foo
Использование аргументов командной строки с argv
Всякий раз, когда скрипт Python вызывается из командной строки, пользователь может предоставить дополнительные аргументы командной строки, которые будут переданы скрипту. Эти аргументы будут доступны для программиста от переменной системы sys.argv
( «ARGV» является традиционным названием используется в большинстве языков программирования, и это означает «ARG ument v Эктор»).
По соглашению, первым элементом в списке sys.argv
является имя самого скрипта Python, а остальные элементы - токены, переданные пользователем при вызове скрипта.
# cli.py
import sys
print(sys.argv)
$ python cli.py
=> ['cli.py']
$ python cli.py fizz
=> ['cli.py', 'fizz']
$ python cli.py fizz buzz
=> ['cli.py', 'fizz', 'buzz']
Вот еще один пример использования argv
. Сначала мы отключаем исходный элемент sys.argv, потому что он содержит имя скрипта. Затем мы объединим остальные аргументы в одном предложении и, наконец, напечатаем это предложение, добавив имя текущего пользователя в систему (чтобы он эмулировал программу чата).
import getpass
import sys
words = sys.argv[1:]
sentence = " ".join(words)
print("[%s] %s" % (getpass.getuser(), sentence))
Алгоритм, обычно используемый при «ручном» анализе нескольких непозиционных аргументов, заключается в sys.argv
списку sys.argv
. Один из способов - перечислить список и поместить каждый его элемент:
# reverse and copy sys.argv
argv = reversed(sys.argv)
# extract the first element
arg = argv.pop()
# stop iterating when there's no more args to pop()
while len(argv) > 0:
if arg in ('-f', '--foo'):
print('seen foo!')
elif arg in ('-b', '--bar'):
print('seen bar!')
elif arg in ('-a', '--with-arg'):
arg = arg.pop()
print('seen value: {}'.format(arg))
# get the next value
arg = argv.pop()
Сообщение об ошибке парсерного анализатора с помощью argparse
Вы можете создавать сообщения об ошибках парсера в соответствии с потребностями вашего скрипта. Это через функцию argparse.ArgumentParser.error
. В приведенном ниже примере показано, как сценарий печатает использование и сообщение об ошибке для stderr
когда --foo
но не --bar
.
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-f", "--foo")
parser.add_argument("-b", "--bar")
args = parser.parse_args()
if args.foo and args.bar is None:
parser.error("--foo requires --bar. You did not specify bar.")
print "foo =", args.foo
print "bar =", args.bar
Предположим, что имя вашего скрипта - sample.py, и мы запускаем: python sample.py --foo ds_in_fridge
Сценарий будет жаловаться на следующее:
usage: sample.py [-h] [-f FOO] [-b BAR]
sample.py: error: --foo requires --bar. You did not specify bar.
Концептуальная группировка аргументов с помощью argparse.add_argument_group ()
Когда вы создаете argparse ArgumentParser () и запускаете свою программу с помощью «-h», вы получаете автоматическое сообщение об использовании, объясняющее, с какими аргументами вы можете управлять своим программным обеспечением. По умолчанию позиционные аргументы и условные аргументы разделяются на две категории, например, вот небольшой скрипт (example.py) и вывод при запуске python example.py -h
.
import argparse
parser = argparse.ArgumentParser(description='Simple example')
parser.add_argument('name', help='Who to greet', default='World')
parser.add_argument('--bar_this')
parser.add_argument('--bar_that')
parser.add_argument('--foo_this')
parser.add_argument('--foo_that')
args = parser.parse_args()
usage: example.py [-h] [--bar_this BAR_THIS] [--bar_that BAR_THAT]
[--foo_this FOO_THIS] [--foo_that FOO_THAT]
name
Simple example
positional arguments:
name Who to greet
optional arguments:
-h, --help show this help message and exit
--bar_this BAR_THIS
--bar_that BAR_THAT
--foo_this FOO_THIS
--foo_that FOO_THAT
Есть несколько ситуаций, когда вы хотите разделить свои аргументы на дополнительные концептуальные разделы, чтобы помочь вашему пользователю. Например, вы можете иметь все параметры ввода в одной группе и все параметры форматирования вывода в другом. Вышеприведенный пример можно настроить для разделения аргументов --foo_*
от аргументов --bar_*
.
import argparse
parser = argparse.ArgumentParser(description='Simple example')
parser.add_argument('name', help='Who to greet', default='World')
# Create two argument groups
foo_group = parser.add_argument_group(title='Foo options')
bar_group = parser.add_argument_group(title='Bar options')
# Add arguments to those groups
foo_group.add_argument('--bar_this')
foo_group.add_argument('--bar_that')
bar_group.add_argument('--foo_this')
bar_group.add_argument('--foo_that')
args = parser.parse_args()
Который производит этот вывод, когда запускается python example.py -h
:
usage: example.py [-h] [--bar_this BAR_THIS] [--bar_that BAR_THAT]
[--foo_this FOO_THIS] [--foo_that FOO_THAT]
name
Simple example
positional arguments:
name Who to greet
optional arguments:
-h, --help show this help message and exit
Foo options:
--bar_this BAR_THIS
--bar_that BAR_THAT
Bar options:
--foo_this FOO_THIS
--foo_that FOO_THAT
Расширенный пример с docopt и docopt_dispatch
Как docopt, с [docopt_dispatch] вы ремесло ваш --help
в __doc__
переменной вашей точки входа модуля. Там вы вызываете dispatch
с doc-строкой в качестве аргумента, чтобы она могла запускать парсер.
Это делается вместо того, чтобы вручную обрабатывать аргументы (которые обычно заканчиваются в высокой циклической структуре if / else), вы оставляете его для отправки, предоставляя только то, как вы хотите обрабатывать множество аргументов.
Это то, на что работает dispatch.on
: вы даете ему аргумент или последовательность аргументов, которые должны запускать функцию, и эта функция будет выполняться с соответствующими значениями в качестве параметров.
"""Run something in development or production mode.
Usage: run.py --development <host> <port>
run.py --production <host> <port>
run.py items add <item>
run.py items delete <item>
"""
from docopt_dispatch import dispatch
@dispatch.on('--development')
def development(host, port, **kwargs):
print('in *development* mode')
@dispatch.on('--production')
def development(host, port, **kwargs):
print('in *production* mode')
@dispatch.on('items', 'add')
def items_add(item, **kwargs):
print('adding item...')
@dispatch.on('items', 'delete')
def items_delete(item, **kwargs):
print('deleting item...')
if __name__ == '__main__':
dispatch(__doc__)