Связывание парсинга аргумента командной строки с инициализацией объекта

У меня есть класс, который имеет около дюжины объектных переменных. Вместе с каждой переменной я хочу предоставить значение по умолчанию, строку справки (для argparse) и строку комментария (для записи в файл данных). Я хочу иметь возможность создавать объекты с помощью:

  1. предоставление явных значений методу init
  2. предоставление значений для использования в командной строке
  3. принимая значения по умолчанию
  4. некоторая комбинация вышеперечисленного.

Когда у меня было только две объектные переменные, я указывал значения по умолчанию в объявлении функции init, я копировал их и строку справки при создании анализатора аргументов и т. Д. Но для многих переменных это становится очень грязным.

Урезанный пример кода ниже - мое текущее решение, которым я вполне доволен, делает именно то, что я хочу, и работает довольно хорошо. Но у меня есть два вопроса:

  1. Это питон?
  2. Наверняка это уже решенная проблема, и есть "стандартный" способ сделать это?

Я осмотрелся здесь и немного погуглил, но мне не удалось найти существующее решение.

# 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.

Конечно, ни один из этих ответов не должен мешать вам делать то, что вам нравится.

Другие вопросы по тегам