заполнить пользовательский класс записи из командной строки через argparse - PullRequest
0 голосов
/ 16 июня 2020

Я хотел бы сохранить параметры, с которыми я запускаю свою программу, в некоторой форме объекта свойств, подобного argparse.Namespace. Сценарий может быть запущен из командной строки, но также может быть вызван напрямую с заданным объектом свойств.

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

Я придумал следующее, немного злоупотребляя (?) системой аннотаций:

import argparse
from typing import Optional

from recordclass import StructClass


def custom_convert(s: str) -> Optional[int]:
    if not s or s.casefold() == "none":
        return None
    return int(s)


class Prop(StructClass("Prop")):
    a: str = "adef"
    b: str = "bdef"
    c: int = 5
    d: custom_convert = None
    hidden = 3  # not annotated, so hidden
    _hidden2: float = 1.1  # hidden as starting with _


parser = argparse.ArgumentParser()
prop_default = Prop()
for k, v in Prop.__annotations__.items():
    if not k.startswith("_"):
        parser.add_argument("--" + k, required=False, type=v, default=prop_default.__getattribute__(k))

args = parser.parse_args()
prop = Prop(**vars(args))
print(prop)

Пока все в порядке. Это также поддерживает некоторые скрытые поля, которые недоступны при настройке из командной строки: не комментируйте их и не делайте их защищенными. Теперь я бы хотел, чтобы произвольные аннотированные, «скрытые в командной строке» поля поддерживались автоматически. Я знаю, что могу поместить их в какой-нибудь список исключений или указать другой префикс, но есть ли более элегантный метод? Возможно, здесь нужно изменить всю структуру настройки, это было бы хорошо.

...