В настоящее время я работаю над интерфейсом командной строки с argparse
. Я получаю проанализированные аргументы как Namespace
объект от arg_parse
. В основном аргументы, поступающие в форме CLI, должны быть переданы до 2 функций. Теперь я ищу умный способ разделить Namespace
так, чтобы я мог просто использовать распаковку.
Следующий пример должен проиллюстрировать то, что мне нужно:
import argparse
ns1 = argparse.Namespace(foo=1)
ns2 = argparse.Namespace(bar=2)
ns3 = argparse.Namespace(foo=1, bar=2)
def f(foo): return foo
def g(bar): return 10 * bar
f(**vars(ns1)) # works
g(**vars(ns2)) # works
f(**vars(ns3)) # does not work, 'bar' is not an argument of f
Я мог бы усердно закодируйте фильтр как в
f_args = ["foo"]
g_args = ["bar"]
f(**{k:v for k, v in vars(ns3).items() if k in f_args}) # works
g(**{k:v for k, v in vars(ns3).items() if k in g_args}) # works
Но это может привести к ошибкам (если сигнатура f
изменится, я должен также помнить об изменении f_args
). Однако я мог бы использовать inspect.getfullargspec
для автоматизации этой части, как в:
import inspect
f_args = inspect.getfullargspec(f).args
Но мне все это кажется хаки sh, и мне было интересно, не упускаю ли я из виду легкий образец для этого?
Обновление
Как указал @ doer_uv c, одним из подходов будет обработка моих функций с помощью параметра "catch all" как в:
def f(foo, **kwargs): return foo
Хотя это жизнеспособное решение, мне было бы любопытно найти решения, в которых мне не нужно трогать подпись самого f
.