sys.argv Python

Содержание
Введение
sys.argv[0]
Необязательный аргумент
Неизвестное число аргументов
Пример
Приём для импорт в REPL
В других языках
Похожие статьи

Введение

Это статья про агрументы, которые передаются в скрипт извне. Например, из терминала.

Передача аргументов в скрипт это распространённая практика для CI/CD.

Про обычные аргументы, то есть такие, которые передаются в функцию внутри модуля, читайте статью *args, **kwargs

Чтобы передать аргументы в Python скрипт из командной строки нужно воспользоваться библиотекой sys

import sys

Далее каждый аргумент нужно принимать с помощью sys.argv

a = sys.argv[0] b = sys.argv[1] c = sys.argv[2] …

sys.argv[0]

Нулевой элемент это название самого скрипта.

# zero.py import sys print(f"First argument argv[0] is {sys.argv[0]}")

python zero.py

Можно передать ещё какие-то аргументы, ошибки не будет.

python zero.py argument

First argument argv[0] is .\zero.py

В Linux

python3 zero.py

First argument argv[0] is zero.py

sys.argv[1]

Первый элемент это первый переданный аргумент.

# one.py import sys print(f"Second argument argv[1] is {sys.argv[1]}")

Такой скрипт нельзя вызвать без аргументов.

python .\one.py

Traceback (most recent call last): File "C:\python\one.py", line 4, in <module> print(f"Second argument argv[1] is {sys.argv[1]}") ~~~~~~~~^^^ IndexError: list index out of range

python .\one.py Test

Second argument argv[1] is Test

О том как сделать скрипт устойчивым к непередаче аргумента читайте в следующей главе.

Необязательный аргумент

Если нужно сохранить возможность не передавать никаких аргументов - можно добавить проверку длинны sys.argv

# one.py import sys if len(sys.argv) > 1: a = sys.argv[1] else: a = None print(f"Second argument argv[1] is {a}")

python .\one.py

Second argument argv[1] is None

python .\one.py Test

Second argument argv[1] is Test

Можно задать строгое условие на количество аргментов:

import sys if len(sys.argv) == 2: a = sys.argv[1] else: a = "default" print("a =", a) print(type(a))

python sysargs.py 2

a = 2 <class 'str'>

python sysargs.py

a = default <class 'str'>

Неизвестное заранее количество аргументов

Что делать если число аргументов заранее неизвестно.

Используем следующее свойство списков в Python

lst = ["a", "b", "c"] print(lst[1:])

['b', 'c']

import sys print(f"Script received positional args: {sys.argv[1:]}")

python positional.py arg1 arg2 'arg as phrase'

Script received positional args: ['arg1', 'arg2', 'arg as phrase']

Обратите внимание, на возможность передавать с помощью кавычек аргументы с пробелами.

Пример

Скрипт add.py, который складывает две строки.

Без проверки на существование аргумента.

# one.py import sys first = sys.argv[1] second = sys.argv[2] print(f"{first} + {second} = {first + second}")

python add.py topbicycle .ru

topbicycle + .ru = topbicycle.ru

В такой скрипт можно передать ровно два аргумента.

Рассмотрим похожий скрипт, успешно принимающий разное количество аргументов.

import sys st = "" for el in sys.argv[1:]: st += el print(st)

В этот скрипт можно передавать разное количество аргументов

python unknown_len.py

python unknown_len.py 1 2

12

python unknown_len.py 1 2 3 a b cde 4 5 None

123abcde45None

Чтобы проделать похожие действия с целыми числами - используем функцию int() так как даже если передать числа, они будут получены как строки.

import sys first = int(sys.argv[1]) second = int(sys.argv[2]) print(f"{first} + {second} = {first + second}")

python add.py 3 4

3 + 4 = 7

Теперь то же самое но для заранее неизвестного числа элементов. Некоторые элементы могут быть неприводимы к типу int.

Для разнообразия используем range(1, len(sys.argv)) вместо sys.argv[1:]

import sys s = 0 x = 0 for i in range(1, len(sys.argv)): try: x = int(sys.argv[i]) except ValueError: x = 0 finally: s += x print(s)

python unknown_len.py 1 2 3 4 5

15

Можно передать в скрипт и нечисловые аргументы

python unknown_len.py 1 2 3 a b cde 4 5 None

15

Можно ничего не передавать, ошибки не будет. Сумма будет равна нулю.

python unknown_len.py

0

РЕКЛАМА хостинга Beget, которым я пользуюсь более десяти лет

Изображение баннера

Конец рекламы хостинга Beget, который я всем рекомендую.

Пример 2

Рассмотрим скрипт words.py из курса от Pluralsight

import sys from urllib.request import urlopen def fetch_words(url): # story = urlopen("https://testsetup.ru/testdata/words_en.txt") story = urlopen(url) story_words = [] for line in story: line_words = line.decode("utf8").split() for word in line_words: story_words.append(word) story.close() return story_words def print_words(story_words): for word in story_words: print(word) def main(): url = sys.argv[1] words = fetch_words(url) print_words(words) if __name__ == "__main__": main()

Этот скрипт не будет работать если не передать нужный url через терминал

python words.py "https://testsetup.ru/testdata/words_en.txt"

Желательно также предусмотреть вызов функции main() после импорта.

В текущем виде будут проблемы

python

Python 3.9.5 (default, Jun 15 2021, 15:30:04) [GCC 9.3.0] on linux Type "help", "copyright", "credits" or "license" for more information.

>>> from words import *
>>> main()

Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/andrei/python/words.py", line 23, in main url = sys.argv[1] IndexError: list index out of range

>>> main("https://testsetup.ru/testdata/words_en.txt")

Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: main() takes 0 positional arguments but 1 was given

Решается проблема добавлением sys.argv[1] в вызов main

def main(url): words = fetch_words(url) print_words(words) if __name__ == "__main__": main(sys.argv[1])

>>> main("https://testsetup.ru/testdata/words_en.txt")

В других языках

В C аналогичную функцию выполняет int argc, char* argv[]

В Bash это встроено по умолчанию .

Автор статьи: Андрей Олегович

Похожие статьи
Command Line Interface
argparse

Поиск по сайту

Подпишитесь на Telegram канал @aofeed чтобы следить за выходом новых статей и обновлением старых

Перейти на канал

@aofeed

Задать вопрос в Телеграм-группе

@aofeedchat

Контакты и сотрудничество:
Рекомендую наш хостинг beget.ru
Пишите на info@urn.su если Вы:
1. Хотите написать статью для нашего сайта или перевести статью на свой родной язык.
2. Хотите разместить на сайте рекламу, подходящую по тематике.
3. Реклама на моём сайте имеет максимальный уровень цензуры. Если Вы увидели рекламный блок недопустимый для просмотра детьми школьного возраста, вызывающий шок или вводящий в заблуждение - пожалуйста свяжитесь с нами по электронной почте
4. Нашли на сайте ошибку, неточности, баг и т.д. ... .......
5. Статьи можно расшарить в соцсетях, нажав на иконку сети: