Связывание парсинга аргумента командной строки с инициализацией объекта
У меня есть класс, который имеет около дюжины объектных переменных. Вместе с каждой переменной я хочу предоставить значение по умолчанию, строку справки (для argparse) и строку комментария (для записи в файл данных). Я хочу иметь возможность создавать объекты с помощью:
- предоставление явных значений методу init
- предоставление значений для использования в командной строке
- принимая значения по умолчанию
- некоторая комбинация вышеперечисленного.
Когда у меня было только две объектные переменные, я указывал значения по умолчанию в объявлении функции init, я копировал их и строку справки при создании анализатора аргументов и т. Д. Но для многих переменных это становится очень грязным.
Урезанный пример кода ниже - мое текущее решение, которым я вполне доволен, делает именно то, что я хочу, и работает довольно хорошо. Но у меня есть два вопроса:
- Это питон?
- Наверняка это уже решенная проблема, и есть "стандартный" способ сделать это?
Я осмотрелся здесь и немного погуглил, но мне не удалось найти существующее решение.
# invoke with python demoArgs.py -a 15 -b 25 -c text
import argparse
class Foo:
defaults = {'a':10,'b':20, 'c':"outFile"}
helpDefs = {'a' : 'the first parameter',
'b' : 'the second paramter',
'c' : 'the third paramter'}
@staticmethod
def parse_args():
parser = argparse.ArgumentParser()
for key in Foo.defaults:
parser.add_argument('-'+ key, help = Foo.helpDefs[key],
default = Foo.defaults[key])
return vars(parser.parse_args())
def __init__(self, a = defaults['a'], b = defaults['b'], c = defaults['c']):
self.a = a
self.b = b
self.c = c
def report(self):
for key in sorted(vars(self)):
print key, "val = ", getattr(self,key), \
", help = ", self.helpDefs[key], \
", def = ", self.defaults[key]
def main():
print "\n an object using all of the defaults"
a = Foo()
a.report()
print "\n an object using the command line values"
args = Foo.parse_args()
b = Foo(**args)
b.report()
print "\n an object using values specified in the code"
c = Foo(30,40,"object")
c.report()
print "\n an object using a perverse combination"
args = Foo.parse_args()
d = Foo(50, c = args['c'])
d.report()
if __name__ == '__main__':
main()
1 ответ
Что касается "питонического" - я бы сказал, нет. Argparse уже довольно мощный. Кто-то, кто хотел бы использовать вашу библиотеку, должен был бы тщательно понять, как она работает и как она обернута чем-то другим (что также потребовало бы понимания того, что она обернула). Это спорно, будет ли усилие стоит. В краткосрочной перспективе вам, вероятно, лучше использовать argparse, а не пытаться упростить что-то, что уже выполняет свою работу (IMHO).
Что касается вопроса № 2 - я серьезно сомневаюсь, что кто-то еще пытался это сделать. Большинство людей обычно просто придерживаются stdlib. Это проще и доступно на всех платформах, где может работать python.
Конечно, ни один из этих ответов не должен мешать вам делать то, что вам нравится.