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