Python разные функции в зависимости от ввода - PullRequest
0 голосов
/ 08 декабря 2010

Я написал программу для решения задач для моей главы по физике, которая берет все данные и делает с ними все возможное.Я использовал длинную строку операторов if, чтобы проверить, какие функции безопасно вызывать (сами функции небезопасны), но я чувствую, что должен быть лучший способ сделать это.

полный код здесь

Вот фрагмент кода нарушителя (по умолчанию Argparse отсутствует):

# EVALUATE:
if args.t and args.ld:
    print 'Velocity:', find_velocity(args.t, args.ld)
if args.t and args.l and args.m:
    print 'Velocity:', find_velocity(args.t, args.l, args.m)
if args.l:
    print 'Longest possible standing wave length:', find_longest_possible_standing_wave_length(args.l)
if args.l and args.m and args.t and args.n:
    print 'Frequency of the standing wave with', args.n, 'nodes:', find_nth_frequency_standing_wave(args.t, args.n, args.l, args.m)
if args.s and args.t and args.n and args.l:
    print 'Frequency of', args.n, 'standing wave:', find_nth_frequency_standing_wave(args.t, args.n, args.l, velocity=args.s)
if args.ld and args.t and args.f:
    print 'Angular wave number: ', find_angular_wave_number(args.ld, args.t, args.f)
if args.p:
    print 'Difference in amplitude of twins:', find_amplitude_difference_of_twins(args.p)
if args.f:
    print 'Angular wave frequency:',  find_angular_wave_frequency(args.f)

Спасибо!

Ответы [ 3 ]

3 голосов
/ 08 декабря 2010

Поместите функции в список, затем отфильтруйте этот список, убедившись, что для каждого имени переменной в этой функции эти аргументы не равны.

Пример:

def func_filter(item, arguments):
    needed_args = item.func_code.co_varnames
    all(map(lambda x: getattr(arguments, x) , needed_args))

funcs = (find_velocity, find_nth_frequency_standing_wave)
funcs = filter(lambda x: func_filter(x, args), funcs)
#now execute all of the remaining funcs with the necessary arguments,
#similar to code in func filter

Дон 'не держите меня за синтаксис, просто дайте мне знать, если я что-то напутал, я только попробовал его на интерпретаторе.

1 голос
/ 08 декабря 2010

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

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


Если вы застряли на этой схеме, вы можете попробовать следующее:

  • сделать dict функции -> обязательные аргументы:

    {find_velocity: ("t", "ld"), ...}
    
  • зациклить на dict и проверить, есть ли у каждого свойства:

    for func, reqs in funcs.items():
        args = [getattr(args, req) for req in reqs]
        if all(args):
            func(*args)
    
0 голосов
/ 08 декабря 2010

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

Вы можете получить доступ к первому аргументу с помощью sys.argv[1], а все остальные аргументы с помощью sys.argv[2:].

Затем вы можете вызвать функцию следующим образом:

locals()[sys.argv[1]](*sys.argv[2:])

При условии, что ваши функции определены в локальном модуле.

...