Как вы получаете имя программы с помощью argparse?

Я использую argparse для анализа аргументов командной строки. Просматривая документацию для argparse, я мог видеть только условие использования другого имени программы.

Я хочу иметь возможность использовать имя программы по умолчанию без импорта sys. Насколько мне известно, в argparse нет ничего, что вернет имя программы.

import argparse

parser = argparse.ArgumentParser()
args = parser.parse_args()

print(dir(args))

И вот вывод:

['__class__', '__contains__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_get_args', '_get_kwargs']

Есть ли другой способ получить имя программы без импорта модуля sys?

Ответ 1

ArgumentParser У экземпляров есть атрибут prog, который, как я думаю, вам нужен.

import argparse

parser = argparse.ArgumentParser()
print('parser.prog: {}'.format(parser.prog))

Я обнаружил это, читая исходный код модуля в Lib/argparse.py - особенно глядя на class ArgumentParser определение. Поскольку имя атрибута не начинается с символа подчеркивания, я предполагаю его общедоступным.

Обновление

Я вижу, что, по крайней мере, в настоящее время атрибут prog экземпляра ArgumentParser является (или был с момента запроса этого вопроса) документирован как в Документация Python 2 и Документация Python 3.

Итак, да, это определенно публично, и в обеих версиях, если он не указан как аргумент ключевого слова при создании ArgumentParser, по умолчанию он равен prog = _os.path.basename(_sys.argv[0]) (где _os и _sys являются частными argparse, которые соответствуют их несимвольным префиксным аналогам. Обратите внимание, что из-за использования os.basename() это будет только имя файла script, а не полный путь к нему, который может (зависит от ОС) был в sys.argv[0].

Ответ 2

Конечно, правильный способ:

>>> import sys
>>> print sys.argv[0]
    scripts/script.py

Но пусть на мгновение у вас есть веская причина, которая мешает вам import sys, но позволяет вам import argparse.

martineau проделал замечательную работу по обнаружению prog, попробуйте:

>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> print parser.prog
    script.py

Как отмечено hpaulj, у этого имени есть только имя файла, а не полный путь, например sys.argv[0], потому что модуль argparse.py использует prog = os.path.basename(sys.argv[0]).

Но argparse должен использовать sys, поэтому он должен быть доступен в пространстве имен argparse. Пусть это проверит:

>>> import argparse
>>> print argparse.__dict__
    { ..., '_sys': <module 'sys' (built-in)>, ... }

Вот оно! Попробуйте использовать _sys:

>>> import argparse
>>> print argparse._sys.argv[0]
    scripts/script.py

Вы используете sys! Конечно, но я не импортировал его, только argparse, вот в чем вопрос!

Конечно, это имеет ряд противопоказаний:

  • Вам не следует использовать переменные с префиксом _ или __ других пространств имен, они используются внутренне.
  • Вы не должны полагаться на импорт других модулей, они могут измениться.
  • Вы не должны полагаться на недокументированные api, они могут измениться.

TL;DR

Это было весело, но просто придерживайтесь import sys, пока argparse не выпустит api для доступа к sys.argv[0].