Значение по умолчанию используется вместо ввода пользователя в argparse - PullRequest
0 голосов
/ 14 мая 2018

У меня проблемы с написанием следующего аргумента, в котором я пытаюсь:

  • если пользователь вводит дату (например, 20180514), используйте дату, введенную пользователем
  • если дата не определена пользователем, используйте параметр по умолчанию, указанный в аргументе.

Это моя часть кода:

parser.add_argument(
    '--date',
    #type=str,
    action='store_true'
    default=datetime.now()-timedelta(days=5))
)

if args.date:
    # Use the User-inputted date
else:
    # Use the default date as stated

Если я использовал флаг action, я получу ошибку со ссылкой __init__() got an unexpected keyword argument 'type'. Если я не использую action и использую флаг type, который я использовал изначально, код возвращается к использованию значения по умолчанию вместо значения, введенного пользователем.

Благодарю за любые советы. Большое спасибо заранее!

Ответы [ 2 ]

0 голосов
/ 14 мая 2018

Есть две проблемы:

  • if args.date: будет всегда истинным, потому что это будет значение по умолчанию или введенное пользователем значение, ни одно из которых не равно false-y (объекты даты и времени пустые строки никогда не бывают).
  • store_true - неправильное действие, потому что оно говорит argparse, что этот переключатель не принимает значения (он установит args.past в True, когда пользователь использует переключатель, все, что следует за --date, будет не рассматривается как часть этого аргумента). Оставьте значение по умолчанию 'store'.

Кроме того, str является типом по умолчанию и неправильным типом, если вы хотите проанализировать пользовательский ввод в экземпляр datetime.

Это работает:

parser.add_argument(
    '--past',
    default=datetime.now() - timedelta(days=5))

Но теперь args.past будет либо string (пользовательский ввод), либо datetime instance (значение по умолчанию). Возможно, вы захотите использовать аргумент type=, который также преобразует вводимые пользователем данные в объект datetime. Такие как:

def to_datetime(s):
    return datetime.strptime(s, '%Y%m%d')

parser.add_argument(
    '--past',
    type=to_datetime,
    default=datetime.now() - timedelta(days=5))

для принятия дат в установленном вами формате ГГГГММДД.

Демо-версия:

>>> from argparse import ArgumentParser
>>> from datetime import datetime, timedelta
>>> def to_datetime(s):
...     return datetime.strptime(s, '%Y%m%d')
...
>>> parser = ArgumentParser(prog='demo')
>>> parser.add_argument(
...     '--past',
...     type=to_datetime,
...     default=datetime.now() - timedelta(days=5))
_StoreAction(option_strings=['--past'], dest='past', nargs=None, const=None, default=datetime.datetime(2018, 5, 9, 20, 42, 34, 806341), type=<function to_datetime at 0x10bf422f0>, choices=None, help=None, metavar=None)
>>> args = parser.parse_args()
>>> args.past
datetime.datetime(2018, 5, 9, 20, 42, 34, 806341)
>>> args = parser.parse_args(['--past', '20180514'])
>>> args.past
datetime.datetime(2018, 5, 14, 0, 0)
0 голосов
/ 14 мая 2018

Почему у вас action='store_true'?

Это означает, что argparse будет игнорировать все, что следует после --date, и вместо этого установит args.date в True или False в зависимости от того, было ли --date предоставлено или нет.

Тебе это тоже не нужно if:

parser.add_argument(
    '--date',
    default=datetime.now()-timedelta(days=5))
)

По сути, все, что вам нужно. Только не забудьте конвертировать args.date в объект datetime, когда вам это нужно.

...