简体   繁体   English

执行子功能的主功能

[英]Master function that executes subfunctions

I have two functions that accept different parametes: 我有两个接受不同参数的函数:

def foo(name, age):
    pass
def bar(color, shape):
    pass

Now, I have a master function that I want to be able to call with the function I want to execute and it's parameters. 现在,我有一个主函数,我希望能够使用我要执行的函数及其参数进行调用。 Since it's a master function that might call either foo or bar, it's called with only two params (the function to be executed and the parameters for this function. 由于它是一个可以调用foo或bar的主函数,因此仅使用两个参数(要执行的函数和该函数的参数)进行调用。

function is a string telling what function to execute function是一个字符串,告诉执行什么功能

params will be a dictionary of parameters (like **kwargs) params将是参数字典(例如** kwargs)

I can do this to make it work: 我可以这样做以使其工作:

def master(function, params):
    if function == 'foo':
        foo(params['name'], params['age'])
    elif function == 'bar':
        foo(params['color'], params['shape'])

And then I call master like: 然后我打电话给师父:

master('foo',{'name': 'John', 'age': 99})

However if master has a lot of subfuntions to call, there's too much conditions and picking the right parameters for each function. 但是,如果master需要调用许多子功能,则条件太多,无法为每个函数选择正确的参数。

So I basically have two questions: 所以我基本上有两个问题:

1) Instead of calling master with the name of the function and then checking this name in a condition, can I directly pass the function to be executed? 1)我可以直接传递要执行的功能,而不是用功能名称调用master,然后在某种情况下检查该名称吗? If so, how do I execute the function then? 如果是这样,我该如何执行该功能?

Something like calling master like this: 像这样打电话给主人:

master(foo(), {'name': 'John', 'age': 99})

2) functions foo and bar don't have **kwargs, however it would be very convinient if I can call them passing just a dictionary and then they assign to each variable their corresponding value from the dict. 2)函数foobar没有** kwargs,但是如果我可以仅通过字典调用它们,然后将它们从dict分配给每个变量,这将非常方便。

So basically, could I do: 所以基本上,我可以这样做:

params = {'name':'John', 'age':99, 'color':red, 'shape':circle}
foo(params)  # I would like to to this even if foo doesn't have **kwargs
bar(params)  # same for bar

So at the end my ideal call of master would be: 因此,最后,我理想的主人呼吁是:

params = {'name':'John', 'age':99, 'color':red, 'shape':circle}

master(foo(), params) # to execute foo
master(bar(), params) # to execute bar

You can pass functions as arguments: 您可以将函数作为参数传递:

def master(func, arguments: dict):
    if func is foo:
        args = arguments["name"], arguments["age"]
    elif func is bar:
        args = arguments["color"], arguments["shape"]

    return func(*args)

This can be done even simpler if you don't know the names of the functions' arguments: 如果您不知道函数参数的名称,则可以更简单地完成此操作:

def master(func, arguments: list):
    return func(*arguments)

A much more generic version is the following: 以下是更为通用的版本:

def master(function, *positional_arguments, **keyword_arguments):
    function(*positional_arguments, **keyword_arguments)

master(foo, 'John', 56)
master(foo, **{'name': 'John', 'age': 56})
master(foo, name='John', age=56)
master(foo, *['John', 56])

function is a first-class object in Python and therefore can be assigned to an identifier, passed as an argument or returned by a function. 函数是Python中的一类对象 ,因此可以分配给标识符,作为参数传递或由函数返回。

The unified way where you don't want to bother of keyword args for a particular function - with inspect.getfullargspec feature: 您不想为特定功能打扰关键字args的统一方法-具有inspect.getfullargspec功能:

import inspect

def foo(name, age):
    print(name, age)

def bar(color, shape):
    print(color, shape)

def master(func, params):
    arg_names = inspect.getfullargspec(func).args
    func(**{k:v for k,v in params.items() if k in arg_names})

params = {'name':'John', 'age':99, 'color':'red', 'shape':'circle'}
master(foo, params)
master(bar, params)

Sample output: 样本输出:

John 99
red circle

Function in python are objects, so yes, you can pass them as a parameter (but do not use parenthesis). python中的函数是对象,因此可以,您可以将它们作为参数传递(但不要使用括号)。

def master(function, **kwargs):
    function(params, kwargs)

Then you call the master: 然后,您致电主人:

master(foo, name='John', age=99...)

You can execute a function through master function not by passing a function as a parameter inside master, but by passing the definition of the function. 您可以通过master函数执行函数,而不是通过在master内部传递函数作为参数,而是通过传递函数定义来执行。 Please follow the example below: 请遵循以下示例:

   def foo(name, age):
      pass

   def bar(color, shape):
      pass

Now consider a master function: 现在考虑一个主函数:

Func param will contain the defination of the function by adding parentheses after function name, it will make it to execute. Func参数将通过在函数名称后添加括号来包含函数的定义,使其执行。

def masterFunc(func, params):
     return func(params)  #  Func param will contain the defination of the function by adding parentheses after function name, it will make it to execute. 

You will use this master function to execute the passed function defination as below: 您将使用此主函数来执行传递的函数定义,如下所示:

masterFunc(foo,{a:1}) #Sample execution

In Python, functions are objects, like everything else. 在Python中,函数是对象,就像其他所有对象一样。 You can pass functions as parameters and execute them very simply. 您可以将函数作为参数传递并非常简单地执行它们。

In your case, 在你的情况下,

 def say_hello(name):
   print "hi ", name

 def say_bye(name, time):
   print name, ", have a good ", time

 say_bye("john", "night")
 john , have a good  night

 def master(fun, **kwargs):
   fun(**kwargs)

 master(say_bye, name='john', time='night')
 john , have a good  night

 params1 = {'name': 'jay', 'time': 'morning'}
 params2 = {'name': 'cole'}

 master(say_hello, **params2)
 hi  cole

 master(say_bye, **params1)
 jay , have a good  morning

this should work. 这应该工作。

You can try with the below approach. 您可以尝试以下方法。

Code

class A:
    def a(self, *args, **kwargs):
        print('A')

    def b(self, *args, **kwargs):
        print('B', args, kwargs)

def main(func, *args, **kwargs):
    x = A()
    if hasattr(x, func):
        func = getattr(x, func)
        func(*args, **kwargs)
    else:
        print('No function name {} defined under class'.format(func))


if __name__ == '__main__':
    func = raw_input('Func_name: a/b')
    main(func, (1), {1:1})

Output 产量

~/del$ python test.py 
Func_name: a/ba
True
A
~/del$ python test.py 
Func_name: a/bb
True
('B', (1, {1: 1}), {})
~/del$

Here, we're using getattr function in __builtin__ . 在这里,我们在__builtin__使用getattr函数。
* First it checks whether there's a function/method named a or b under the instance of class A . *首先,它检查class A的实例下是否有一个名为ab的函数/方法。 * If yes, then only it will getattr from it and execute passing the args and kwargs. *如果是的话,那么只有将getattr距离,并执行传递指定参数和kwargs。 * If somebody passes function name not defined, it will not crash and return saying the needful statement there. *如果有人通过了未定义的函数名,它将不会崩溃并返回在那儿说需要的语句。

Hope this helps ! 希望这可以帮助 !

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM