Zoeken…


Invoering

De meeste opdrachtregelprogramma's vertrouwen op argumenten die aan het programma worden doorgegeven bij de uitvoering ervan. In plaats van te vragen om invoer, verwachten deze programma's dat gegevens of specifieke vlaggen (die Booleans worden) worden ingesteld. Hierdoor kunnen zowel de gebruiker als andere programma's het Python-bestand uitvoeren en het gegevens doorgeven terwijl het start. In deze sectie wordt de implementatie en het gebruik van opdrachtregelargumenten in Python uitgelegd en gedemonstreerd.

Hallo wereld in argparse

Het volgende programma zegt hallo tegen de gebruiker. Het neemt één positioneel argument, de naam van de gebruiker, en kan ook de begroeting worden verteld.

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!

Lees de argparerdocumentatie voor meer informatie.

Basisvoorbeeld met docopt

docopt zet parsering van opdrachtregelargumenten op zijn kop. In plaats van de argumenten te parseren, schrijft u gewoon de gebruikstring voor uw programma en docopt ontleedt de gebruikstring en gebruikt deze om de opdrachtregelargumenten te extraheren.

"""
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)

Voorbeeldruns:

$ 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'}

Onderling uitsluitende argumenten met argparse

Als u wilt dat twee of meer argumenten elkaar uitsluiten. U kunt de functie argparse.ArgumentParser.add_mutually_exclusive_group() . In het onderstaande voorbeeld kan foo of bar bestaan, maar niet beide tegelijk.

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

Als u het script probeert uit te voeren met zowel --foo als --bar argumenten, zal het script klagen met het onderstaande bericht.

error: argument -b/--bar: not allowed with argument -f/--foo

Opdrachtregelargumenten gebruiken met argv

Wanneer een Python-script wordt aangeroepen vanaf de opdrachtregel, kan de gebruiker aanvullende opdrachtregelargumenten opgeven die aan het script worden doorgegeven. Deze argumenten zullen voor de programmeur beschikbaar zijn via de systeemvariabele sys.argv ("argv" is een traditionele naam die in de meeste programmeertalen wordt gebruikt en het betekent " arg ument v ector").

Volgens afspraak is het eerste element in de sys.argv lijst de naam van het Python-script zelf, terwijl de rest van de elementen de tokens zijn die door de gebruiker worden doorgegeven wanneer het script wordt aangeroepen.

# 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']

Hier is nog een voorbeeld van het gebruik van argv . We verwijderen eerst het initiële element van sys.argv omdat het de naam van het script bevat. Vervolgens combineren we de rest van de argumenten in een enkele zin en drukken we die zin uiteindelijk af, voorafgegaan door de naam van de momenteel ingelogde gebruiker (zodat deze een chatprogramma emuleert).

import getpass
import sys

words = sys.argv[1:]
sentence = " ".join(words)
print("[%s] %s" % (getpass.getuser(), sentence))

Het algoritme dat gewoonlijk wordt gebruikt bij het "handmatig" ontleden van een aantal niet-positionele argumenten is om de sys.argv lijst te sys.argv . Een manier is om de lijst te doorlopen en elk element ervan te openen:

# 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()

Aangepast parserfoutbericht met argparse

U kunt parserfoutmeldingen maken op basis van uw scriptbehoeften. Dit argparse.ArgumentParser.error via de functie argparse.ArgumentParser.error . Het onderstaande voorbeeld toont het script dat een gebruik afdrukt en een foutmelding naar stderr wanneer --foo wordt gegeven maar niet --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

Ervan uitgaande dat uw scriptnaam sample.py is en we uitvoeren: python sample.py --foo ds_in_fridge

Het script zal het volgende klagen:

usage: sample.py [-h] [-f FOO] [-b BAR]
sample.py: error: --foo requires --bar. You did not specify bar.

Conceptuele groepering van argumenten met argparse.add_argument_group ()

Wanneer u een argument ArgumentParser () maakt en uw programma uitvoert met '-h', krijgt u een automatisch bericht waarin wordt uitgelegd met welke argumenten u uw software kunt uitvoeren. Standaard zijn positionele argumenten en voorwaardelijke argumenten onderverdeeld in twee categorieën, hier is bijvoorbeeld een klein script (example.py) en de uitvoer wanneer u python example.py -h uitvoert.

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

Er zijn enkele situaties waarin u uw argumenten wilt opsplitsen in verdere conceptuele secties om uw gebruiker te helpen. U wilt bijvoorbeeld alle invoeropties in één groep hebben, en alle uitvoeropmaakopties in een andere. Het bovenstaande voorbeeld kan worden aangepast om de --foo_* args zo te scheiden van de --bar_* args.

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()

Die deze uitvoer produceert wanneer python example.py -h wordt uitgevoerd:

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

Geavanceerd voorbeeld met docopt en docopt_dispatch

Net als bij docopt, maak je met [docopt_dispatch] je --help in de __doc__ variabele van je entry- __doc__ . Daar noem je dispatch met de doc-string als argument, zodat de parser eroverheen kan worden uitgevoerd.

Als je dat doet, laat je de argumenten (die meestal in een hoge cyclomatische if / else-structuur eindigen) niet over, maar laat je deze verzenden en geef je alleen aan hoe je met de set argumenten wilt omgaan.

Dit is waar de dispatch.on decorator voor is: je geeft het het argument of de reeks argumenten die de functie zou moeten activeren, en die functie zal worden uitgevoerd met de overeenkomende waarden als parameters.

"""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__)


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow