Як розібрати аргументи командного рядка в Python

Хочете запускати сценарії 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

Ми можемо прокрутити вектор аргументів за допомогою простого циклу for і функції перерахування:

# 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:].

  Виправте помилку Powerbeats Pro, яка не заряджається з правого боку

Тут нам знадобиться рядок повідомлення та ім’я файлу. Давайте використовувати 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

Список аргументів містить позиційний аргумент інший_аргумент.

# 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»).

$ ls
main.py  thisfile.txt
$ cat thisfile.txt
HELLO

Як аналізувати аргументи командного рядка за допомогою Argparse

Модуль argparse, також вбудований у стандартну бібліотеку Python, надає функціональність для аналізу аргументів командного рядка, а також створення інтерфейсів командного рядка.

  Як заборонити Chrome додавати користувацькі пошукові системи

Щоб розібрати аргументи командного рядка, давайте імпортуємо клас 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) для рядка повідомлення, але ми не надали жодного значення для аргументу file.

І ми отримуємо помилку про те, що потрібен аргумент file.

$ 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

У просторі імен аргументів файл і повідомлення мають значення «Немає».

# 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.