"Как использовать необязательные позиционные аргументы в Argparse?"
У меня есть скрипт, который должен использоваться следующим образом:
usage: installer.py dir [-h] [-v]
Аргумент <code>dir</code>
является позиционным и определяется следующим образом:
parser.add_argument('dir', default=os.getcwd())
Я хочу, чтобы <code>dir</code>
стал необязательным аргументом: если он не указан, должен использоваться текущий рабочий каталог (cwd
).
К сожалению, когда я не указываю аргумент <code>dir</code>
, я получаю ошибку: <code>Error: Too few arguments</code>
.
Как я могу сделать так, чтобы этот аргумент стал необязательным и по умолчанию использовал текущий рабочий каталог?
1 ответ(ов)
Краткий ответ
Как уже было показано в двух предыдущих ответах, вы можете принять необязательный позиционный аргумент, используя nargs='?'
. Вы также можете сразу преобразовать аргумент в тип Path
и/или сократить текущую директорию до .
:
myfile.py
import argparse
import pathlib
parser = argparse.ArgumentParser()
parser.add_argument("dir", nargs="?", default=".", type=pathlib.Path)
parsed_args = parser.parse_args()
print("Установка в", parsed_args.dir.resolve())
$ python myfile.py
Установка в /users/myname/myfolder
$ python myfile.py /usr/bin/
Установка в /usr/bin
Более длинный ответ
Поскольку вы также упоминаете флаги True/False -h
и -v
в вашем вопросе, эти примеры могут быть полезны:
Флаги (например, -v
)
Мы можем называть необязательные параметры, которые не принимают аргументы, "флагами". С флагами нас интересует только то, заданы они или нет. -h
— это флаг, который автоматически добавляется библиотекой argparse (вместе с длинной версией --help
), поэтому мы не должны его переопределять. Если говорить о -v
, то:
myfile.py
import argparse
parser = argparse.ArgumentParser()
parser.add_argument(
"-v",
"--version",
action="store_true")
parsed_args = parser.parse_args()
if parsed_args.version:
print("Флаг версии задан")
else:
print("Флаг версии не задан")
Обратите внимание, что второй аргумент в add_argument()
– это более длинное имя для параметра. Оно не обязательно, но делает ваш код более читаемым (parsed_args.version
против parsed_args.v
) и делает вызовы вашего установщика более явными.
$ python myfile.py -v
Флаг версии задан
$ python myfile.py --version
Флаг версии задан
$ python myfile.py
Флаг версии не задан
Необязательные аргументы (например, --installdir /usr/bin/
)
Можно утверждать, что в вашем случае вам будет лучше использовать необязательный аргумент, вместо позиционного.
myfile.py
import argparse
import pathlib
parser = argparse.ArgumentParser()
parser.add_argument(
"-i",
"--installdir", # Необязательное (но рекомендуемое) длинное имя
type=pathlib.Path,
default="/bin"
)
parsed_args = parser.parse_args()
print("Установка в", parsed_args.installdir)
$ python myfile.py -i /usr/bin/
Установка в /usr/bin
$ python myfile.py --installdir /usr/bin/
Установка в /usr/bin
$ python myfile.py
Установка в /bin
Парсинг булевых значений с помощью argparse
Почему используется string.join(list), а не list.join(string)?
Создание словаря с помощью генератора словарей
Как получить полный путь к директории текущего файла?
Найти все файлы с расширением .txt в директории на Python