Искате ли да изпълнявате скриптове на Python с аргументи от командния ред? Научете как да анализирате аргументите на командния ред с помощта на модулите sys, getopt и argparse в Python.
В Python, когато искате да прочетете въведеното от потребителя, ще използвате функцията input(). За някои приложения обаче може да искате да предадете определени аргументи, докато изпълнявате скрипта в командния ред.
В този урок ще научим как да изпълняваме скрипт на Python с опции и аргументи в командния ред. След това ще научим как да използваме вградените модули на Python, за да анализираме такива опции и аргументи.
Нека да започнем!
Съдържание
Разбиране на sys.argv в Python
Ако сте програмирали на C, знаете, че един от най-лесните начини за предаване на аргументи към програмата е чрез командния ред. За да направите това, можете да структурирате основната функция така:
#include<stdio.h> int main(int argc, char **argv){ //argc: argument count //argv: argument vector //do something on the args return 0; }
Тук argc означава брой аргументи, а argv означава вектор на аргументи.
Изпълнение на Python скриптове с аргументи от командния ред
В Python можете да стартирате скрипта на Python в командния ред, като използвате python3 filename.py. Когато правите това, можете също да подадете произволен брой аргументи от командния ред:
$ python3 filename.py arg1 arg2 ... argn
Модулът sys предоставя поддръжка извън кутията за достъп и обработка на тези аргументи на командния ред. sys.argv е списъкът с всички аргументи на командния ред, които предаваме, когато изпълняваме скрипта на Python.
Ето пример, в който изпълняваме main.py с аргументи от командния ред:
$ python3 main.py hello world python script
Можем да преминем през вектора на аргумента, като използваме проста функция за цикъл и изброяване:
# main.py import sys for idx, arg in enumerate(sys.argv): print(f"arg{idx}: {arg}")
# Output arg0:main.py arg1:hello arg2:world arg3:python arg4:script
Виждаме, че първият аргумент (с индекс 0) е името на Python файла. Следващите аргументи започват от индекс 1.
Това е минимална работеща програма, която приема и обработва аргументи от командния ред. Виждаме обаче някои проблеми:
- Как потребителите на програмата знаят какви аргументи да подадат?
- И какво означават тези аргументи?
Това не е много ясно. За да разрешите това, можете да използвате модулите getopt или argparse. И ще научим това в следващите раздели.✅
Разбор на аргументи от командния ред с помощта на getopt на Python
Нека научим как да анализираме аргументите на командния ред с помощта на вградения модул getopt.
След като импортирате getopt от модула getopt, можете да посочите аргументите за анализиране и кратките опции и дългите опции, с които да стартирате скрипта. Трябва да анализираме всички аргументи, започващи от индекс 1 в sys.argv. Така че срезът за анализ е sys.argv[1:].
Тук ще ни трябва низ за съобщение и име на файл. Нека използваме m и f като кратки опции и съобщение и файл като дълги опции.
Но как да гарантираме, че конкретна опция изисква аргумент?
- В кратките опции можете да накарате опция да изисква аргумент, като добавите двоеточие (:) след краткото име на опцията.
- По подобен начин в дългите опции можете да добавите знак = след дългата опция. Можем да уловим тези опции и съответните им аргументи.
Добавяйки ги, ще имаме следния код в main.py:
# main.py import sys from getopt import getopt opts, args = getopt(sys.argv[1:],'m:f:',['message=","file="]) print(opts) print(args)
Тук променливата opts съдържа опциите и аргументите като списък от кортежи. Всеки друг позиционен аргумент, който предаваме, ще бъде събран в променлива args.
Можем да предадем съобщението и името на файла, за да стартираме скрипта, и можем да използваме или кратките опции, или дългите опции.
Изпълнявайки main.py с дългите опции, имаме:
$ python3 main.py --message hello --file somefile.txt
Имаме опциите и аргументите като кортежи в променливата opts. Тъй като не сме предали нито един позиционен аргумент, args е празен списък.
# Output [("--message', 'hello'), ('--file', 'somefile.txt')] []
По същия начин можем да използваме и кратките опции, както е показано:
$ python3 main.py -m hello -f somefile.txt
# Output [('-m', 'hello'), ('-f', 'somefile.txt')] []
⚠️ Кратката опция -m в този пример не трябва да се бърка с флага на командния ред -m, който се използва за изпълнение на модул като основен модул при изпълнение на скрипт на Python.
Например ще използвате python3 -m unittest main.py, за да стартирате unittest като основен модул, когато изпълнявате main.py.
Споменахме, че всички други позиционни аргументи, които предаваме, ще бъдат събрани в променливата args. Ето един пример:
$ python3 main.py -m hello -f somefile.txt another_argument
Списъкът с аргументи съдържа позиционния аргумент other_argument.
# Output [('-m', 'hello'), ('-f', 'somefile.txt')] ['another_argument']
Тук opts е списък от кортежи. Така че можем да преминем през него, да разопаковаме кортежа и да извадим аргументите, съответстващи на конкретните опции.
Но какво правим с името на файла и съобщението, след като сме обработили тези аргументи? Ще отворим файла в режим на запис и ще запишем низа на съобщението, преобразуван в главни букви, във файла.
# main.py import sys from getopt import getopt opts, args = getopt(sys.argv[1:],'m:f:',['message=","file="]) print(opts) print(args) for option, argument in opts: if option == "-m': message = argument if option == '-f': file = argument with open(file,'w') as f: f.write(message.upper())
Нека стартираме main.py с кратките опции и аргументите на командния ред.
$ python main.py -m hello -f thisfile.txt [('-m', 'hello'), ('-f', 'thisfile.txt')] []
След като стартираме main.py, можем да видим ‘thisfile.txt’ в нашата работна директория. Той съдържа низа ‘hello’, преобразуван в главни букви (‘HELLO’).
$ ls main.py thisfile.txt
$ cat thisfile.txt HELLO
Как да анализирате аргументите на командния ред с Argparse
Модулът argparse, също вграден в стандартната библиотека на Python, предоставя функционалност за анализиране на аргументи на командния ред и също така изграждане на интерфейси на командния ред.
За да анализираме аргументите на командния ред, нека импортираме класа ArgumentParser от модула argparse. Тук създадохме arg_parser, обект на ArgumentParser:
from argparse import ArgumentParser arg_parser = ArgumentParser()
След това бихме искали да добавим два аргумента от командния ред:
- съобщение: низът на съобщението и
- файл: името на файла, с който искаме да работим.
Сега извикваме метода add_argument() на arg_parser, за да добавим и двата аргумента. В извикването на метода add_argument() можете да зададете помощ на низ (описание на аргумента).
arg_parser.add_argument('message',help='message string') arg_parser.add_argument('file',help='filename')
Досега сме инстанциирали arg_parser и сме добавили аргументите на командния ред. Когато програмата се изпълнява от командния ред, можете да използвате метода parse_args() на arg_parser, за да получите стойностите на аргументите.
Тук улавяме пространството от имена на аргументи в променливата args. Така че можете да използвате args.argument_name, за да получите стойностите на аргументите.
След като получим стойностите на аргументите, записваме низа на съобщението с разменен регистър (използвайки метода на низ swapcase()) във файла.
args = arg_parser.parse_args() message = args.message file = args.file with open(file,'w') as f: f.write(message.swapcase())
Обединявайки всичко това, ето нашия файл main.py:
# main.py from argparse import ArgumentParser arg_parser = ArgumentParser() arg_parser.add_argument('message',help='message string') arg_parser.add_argument('file',help='filename') args = arg_parser.parse_args() print(args) message = args.message file = args.file with open(file,'w') as f: f.write(message.swapcase())
Разбиране на използването на аргументи от командния ред
За да разберете използването на аргументите при стартиране на main.py, можете да използвате опцията –help long, както е показано:
$ python3 main.py --help usage: main.py [-h] message file positional arguments: message message string file filename optional arguments: -h, --help show this help message and exit
Няма незадължителни аргументи и както съобщението, така и файлът са задължителни позиционни аргументи. Като алтернатива можете също да използвате кратката опция -h:
$ python3 main.py -h usage: main.py [-h] message file positional arguments: message message string file filename optional arguments: -h, --help show this help message and exit
Както се вижда, и двата аргумента са позиционни по подразбиране. Така че, ако не подадете един или повече от тези аргументи, ще попаднете на грешки.
Тук сме предали позиционен аргумент (Hello) за низа на съобщението, но не сме предоставили никаква стойност за аргумента на файла.
И получаваме грешка, че се изисква файловият аргумент.
$ python3 main.py Hello usage: main.py [-h] message file main.py: error: the following arguments are required: file
Когато стартираме main.py с двата позиционни аргумента, виждаме, че пространството от имена args съдържа стойностите на аргументите.
$ python3 main.py Hello file1.txt
# Output Namespace(file="file1.txt", message="Hello")
Сега, ако разгледаме съдържанието на текущата работна директория, виждаме, че скриптът създава файла ‘file1.txt’:
$ ls file1.txt main.py
Оригиналният низ на съобщението е ‘Hello’; след смяна на регистъра, низът на съобщението във файла ‘file1.txt’ е ‘hELLO’.
$ cat file1.txt hELLO
Как да направите аргументите на командния ред незадължителни
За да направите тези аргументи на командния ред незадължителни, можете да поставите пред името на аргумента –.
Нека модифицираме main.py, за да направим както съобщението, така и аргументите на файла незадължителни.
# main.py from argparse import ArgumentParser arg_parser = ArgumentParser() arg_parser.add_argument('--message',help='message string') arg_parser.add_argument('--file',help='filename')
Тъй като аргументите на командния ред са незадължителни, можем да зададем стойности по подразбиране за тези аргументи.
if args.message and args.file: message = args.message file = args.file else: message="Python3" file="myfile.txt"
В този момент файлът main.py съдържа следния код:
# main.py from argparse import ArgumentParser arg_parser = ArgumentParser() arg_parser.add_argument('--message',help='message string') arg_parser.add_argument('--file',help='filename') args = arg_parser.parse_args() print(args) if args.message and args.file: message = args.message file = args.file else: message="Python3" file="myfile.txt" with open(file,'w') as f: f.write(message.swapcase())
Ако проверим употребата, виждаме, че и съобщението, и файлът са незадължителни аргументи. Което означава, че сега можете да стартирате main.py без тези два аргумента.
$ python3 main.py --help usage: main.py [-h] [--message MESSAGE] [--file FILE] optional arguments: -h, --help show this help message and exit --message MESSAGE message string --file FILE filename
$ python3 main.py
В пространството на имената на аргументите файлът и съобщението са None.
# Output Namespace(file=None, message=None)
Виждаме, че се използват името на файла и съобщението по подразбиране „myfile.txt“ и „Python3“. Файлът „myfile.txt“ вече е в работната директория:
$ ls file1.txt main.py myfile.txt
И съдържа низа „Python3“ с разменени регистър на буквите:
$ cat myfile.txt pYTHON3
Можете също така да използвате аргументите –message и –file, за да направите командата по-четлива.
$ python3 main.py --message Coding --file file2.txt
# Output Namespace(file="file2.txt", message="Coding")
Виждаме „file2.txt“ в работната директория:
$ ls file1.txt file2.txt main.py myfile.txt
И съдържа низа „CODING“, както се очаква.
$ cat file2.txt cODING
Заключение
Ето обобщение на това, което научихме в този урок:
- Подобно на езика за програмиране C, в Python можете да получите достъп до аргументите на командния ред, като преминете през вектора на аргументите sys.argv. sys.argv[0] е името на скрипта на Python. Така че ни интересува анализирането на аргументите sys.argv[1:].
- Въпреки това, за да подобрите четливостта и да можете да добавяте опции, можете да използвате модулите getopt и argparse.
- Можете да използвате модула getopt, за да анализирате списъка с аргументи на командния ред, започвайки от индекс 1 до края на списъка. Можете да посочите както къси опции, така и дълги опции.
- Когато дадена опция приема аргумент, можете да посочите двоеточие (:) и = съответно след кратката опция и дългата опция.
- С модула argparse на Python можете да създадете обект на ArgumentParser и да използвате метода add_argument(), за да добавите необходим позиционен аргумент. Използвайте — преди името на аргумента, за да го направите незадължителен.
- За да извлечете стойностите на аргументите на командния ред, извикайте метода parse_args() на обекта ArgumentParser.
След това научете как да извършвате защитено хеширане в Python.