Есть ли хитрый способ вызова одной функции, которая по очереди вызывает несколько функций с различным количеством и типами аргументов? - PullRequest
0 голосов
/ 09 декабря 2018

В Python 2.7 у меня есть несколько функций, которые я не могу изменить, просто использую.Три из них являются «передними» и три из них являются «задними»;давайте назовем их f1 (), f2 (), f3 (), r1 (), r2 (), r3 ().И у меня также есть 17 функций с различными номерами и типами параметров с разными ключевыми словами, например:

function01( par1='hello' , par2=847, par3=True , par4=17.821 , ........... )
function02( par43=(8.3+17.9i) , par21='august' )

и т. Д.

Мне нужно вызвать их все 17 следующим образом:

f1()
f2()
f3()
functionNN(............................)
r1()
r2()
r3()

Этот блок кода 17 раз (для NN = от 1 до 17)!

Есть хитрый способ сделать это без записи 17 блоков ??

*** ДОБАВЛЕННАЯ ИНФОРМАЦИЯ ... Теперь у меня есть ужасный код:

#block1
f1()
f2()
f3()
function01( par1=..., par2=..., par3=..., par4=...................)
r1()
r2()
r3()

#block2
f1()
f2()
f3()
function02( par43=..., par21=...)
r1()
r2()
r3()

#block3
f1()
f2()
f3()
function03( par17=..., par37=..., par11=...)
r1()
r2()
r3()

#block4
.......
.......
.......
.......
.......
#block17
.......

И одна из 17 функций имеет "безымянные" параметры.: -S

Ответы [ 6 ]

0 голосов
/ 09 декабря 2018

Составьте список с функциями и их параметрами:

ff=[ [function01, [10,20,"something"],  dict(par1='hello', par2=847, par3=True, par4=17.821)],
     [function02, [],                   dict(par43=(8.3+17.9i), par21='august')],
     [function03, [1,2,"hello"],        {}],
     ...
    ]

for  i in range(17):
        f1()
        f2()
        f3()

        posargs=ff[i][1]        # positional args
        kw=ff[i][2]             # keyword args for function_i
        ff[i][0](*posargs,**kw) # calling function_i

        r1()
        r2()
        r3()

Вы также можете изменить параметры позже.Например:

ff[1][2]["par21"]="december"

new_kw_func02= dict(par43=(1+2i), par21='december'])
ff[1][2]= new_kw_func02

new_pargs_func03=[10,20,"World"]
ff[2][1]= new_pargs_func03
0 голосов
/ 09 декабря 2018

Взгляните на contextlib module .Очень простой пример

from contextlib import ContextDecorator

def front1():
    print('print from front1')

def front2():
    print('print from front2')

def front3():
    print('print from front3')


def rear1():
    print('print from rear1')

def rear2():
    print('print from rear2')

def rear3():
    print('print from rear3')

class mycontext(ContextDecorator):
    def __enter__(self):
        front1()
        front2()
        front3()
        return self

    def __exit__(self, *exc):
        rear1()
        rear2()
        rear3()
        return False

@mycontext()
def foo():
    print('print from foo')

@mycontext()
def bar():
    print('print from bar')

if __name__ == '__main__':
    foo()
    bar()

    # or as alternative
    # my_funcs = [foo, bar]
    # for func in my_funcs:
        # func()

output

print from front1
print from front2
print from front3
print from foo
print from rear1
print from rear2
print from rear3
print from front1
print from front2
print from front3
print from bar
print from rear1
print from rear2
print from rear3
0 голосов
/ 09 декабря 2018

Вы также можете использовать globlas() следующим образом:

for i in range(1, 18):
    f1()
    f2()
    f3()
    globals()['function' + str(i).zfill(2)]() # pass the par here, but I dont know the rules
    r1()
    r2()
    r3()

globals() возвращает dict, что функции в глобальных масштабах будут доступной формой dict.Для получения дополнительной информации о globals() прочитайте Здесь .

0 голосов
/ 09 декабря 2018

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

Пример:

fn_list = [function01, function02...]
[fn() for fn in fn_list]

или

def wrapping_func(args_list): (or use *args, **kwargs syntax)
    function01(args_list[0])
    function02(args_list[1])
0 голосов
/ 09 декабря 2018

Функции похожи на объекты, вы можете упаковать их все в список и вызвать их из него.

, например:

def fun0():
    print(0)

def fun1():
    print(1)

def fun2():
    print(2)

def fun3():
    print(3)

funlist = [fun0, fun1, fun2, fun3]

for fun in funlist:
    fun()

В вашем случае вам также потребуетсяупакуйте параметры, так что вам придется использовать что-то вроде этого:

N = 4 

funlist = [fun0, fun1, fun2, fun3]

paramlist = [[params0], [params1], [params2], [params3]]

for i in range(4):
    funlist[i](*paramlist[i])
0 голосов
/ 09 декабря 2018

Почему бы не использовать цикл, например:

for i in range(17):
    f1()
    f2()
    ....
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...