Как отличить значение по умолчанию от заданного пользователем значения? - PullRequest
0 голосов
/ 15 декабря 2018

Я использую Python 3 argparse для получения аргументов командной строки.У меня есть необязательный аргумент со значением по умолчанию.Когда я читаю его значение, можно ли узнать, вводил ли пользователь значение вручную или это значение по умолчанию?

Ранее я проектировал, как указано выше.Теперь я хочу сохранить настройки из предыдущего использования.Итак, если пользователь не вводил никакого значения в необязательный аргумент, я хочу взять значение из предыдущего использования (если оно есть).Итак, я хочу определить, является ли значение значением по умолчанию или заданным пользователем значением.

Редактировать 1 : у меня есть несколько таких аргументов.Я знаю, что могу удалить значение по умолчанию для аргументов и назначить их программно позже.Я просто хочу знать, есть ли более простое решение для этого

Ответы [ 2 ]

0 голосов
/ 15 декабря 2018

Самый надежный способ определить, предоставил ли пользователь значение, - оставить значение по умолчанию None.Пользователь не может сказать, что он произведет то же самое.Затем после разбора все, что вам нужно сделать, это:

if args.myval is None:
    # no user input, set my own special default
else:
    # user value

Если вы установите default=argparse.SUPPRESS, атрибут будет опущен из пространства имен args.Но тестирование для этого случая немного более неловко.

args.myval

вызовет ошибку, которую вы можете поймать.Или вы можете использовать hasattr(args, 'myval'). Or handle the missing key in vars (args) `.

Внутренне parse_args поддерживает список (на самом деле set) действий, которые он" видел ".Это используется для проверки необходимых действий.Но это не доступно для пользователей.Если бы это было возможно, опытные пользователи могли бы выполнять более широкий спектр совместных тестов.

In [28]: import argparse
In [29]: parser = argparse.ArgumentParser()
In [30]: a1 = parser.add_argument('-f','--foo')

Тест без значения:

In [31]: args = parser.parse_args([])
In [32]: args
Out[32]: Namespace(foo=None)         # foo is present
In [33]: args.foo is None
Out[33]: True

Измените значение по умолчанию на SUPPRESS:

In [35]: a1.default = argparse.SUPPRESS
In [36]: args = parser.parse_args([])
In [37]: args
Out[37]: Namespace()          # foo is missing
In [38]: args.foo
AttributeError: 'Namespace' object has no attribute 'foo'

Мы можем поместить args.foo в блок try: except AttributeError.

In [39]: hasattr(args, 'foo')
Out[39]: False

Или проверить словарь на наличие пропущенных значений

In [46]: vars(args)
Out[46]: {}
In [47]: vars(args).get('foo') is None
Out[47]: True
In [48]: 'foo' in vars(args)
Out[48]: False

По умолчанию наиболее полезнокогда он предоставляет действительное, полезное значение и избавляет вас от лишнего тестирования после анализа.

0 голосов
/ 15 декабря 2018

если пользователь не вводил никакого значения в необязательный аргумент, я хочу взять значение из предыдущего использования (если есть).Итак, я хочу определить, является ли значение значением по умолчанию или заданным пользователем значением.

Тогда вы не хотите указывать значение по умолчанию;сделать параметр необязательным (например, Argparse необязательные позиционные аргументы? ), а затем явно проверить его наличие или отсутствие в результирующем объекте пространства имен и сделать соответствующую вещь в логике кода - предположительно, проверить значение впредыдущее использование и затем предоставляют значение по умолчанию в качестве последнего средства.(Думайте о значениях по умолчанию как о логике быстрого доступа для обработки отсутствия значения; вам нужна более сложная логика, поэтому лучше заменить эту систему, чем пытаться обойти ее.)

...