简体   繁体   English

透明地通过带有可变参数列表的 function

[英]Transparently passing through a function with a variable argument list

I am using Python RPyC to communicate between two machines.我正在使用 Python RPyC 在两台机器之间进行通信。 Since the link may be prone to errors I would like to have a generic wrapper function which takes a remote function name plus that function's parameters as its input, does some status checking, calls the function with the parameters, does a little more status checking and then returns the result of the function call. Since the link may be prone to errors I would like to have a generic wrapper function which takes a remote function name plus that function's parameters as its input, does some status checking, calls the function with the parameters, does a little more status checking and然后返回 function 调用的结果。 The wrapper should have no knowledge of the function, its parameters/parameter types or the number of them, or the return value for that matter, the user has to get that right;包装器不应该知道 function,它的参数/参数类型或它们的数量,或者返回值,用户必须正确; it should just pass them transparently through.它应该只是透明地通过它们。

I get the getattr(conn.root, function)() pattern to call the function but my Python expertise runs out at populating the parameters.我得到getattr(conn.root, function)()模式来调用 function 但我的 Python 专业知识在填充参数时用完了。 I have read various posts on the use of *arg and **kwarg , in particular this one , which suggests that it is either difficult or impossible to do what I want to do.我已经阅读了有关使用*arg**kwarg的各种帖子,尤其是这篇文章,这表明做我想做的事情要么困难要么不可能。 Is that correct and, if so, might there be a scheme which would work if I, say, ensured that all the function parameters were keyword parameters?这是正确的吗?如果是这样,如果我确保所有 function 参数都是关键字参数,是否有可行的方案?

I do own both ends of this interface (the caller and the called) so I could arrange to dictionary-ise all the function parameters but I'd rather not make my API too peculiar if I could possibly avoid it.我确实拥有这个接口的两端(调用者和被调用者),所以我可以安排对所有 function 参数进行字典化,但如果我可以避免的话,我宁愿不要让我的 API 太奇特。

Edit: the thing being called, at the remote end of the link, is a class with very ordinary methods, eg;编辑:在链接的远程端被调用的是一个 class 具有非常普通的方法,例如;

def exposed_a(self)
def exposed_b(self, thing1)
def exposed_c(self, thing1=None)
def exposed_d(self, thing1=DEFAULT_VALUE1, thing2=None)
def exposed_e(self, thing1, thing2, thing3=DEFAULT_VALUE1, thing4=None)
def exposed_f(self, thing1=None, thing2=None)

...where the types of each argument (and the return values) could be string, dict, number or list. ...其中每个参数(和返回值)的类型可以是字符串、字典、数字或列表。

And it is indeed, trivial, my Goggle fu had simply failed me in finding the answer.确实,微不足道,我的 Goggle fu 让我无法找到答案。 In the hope of helping anyone else who is inexperienced in Python and is having a Google bad day:希望能帮助那些在 Python 方面没有经验并且在 Google 遇到麻烦的人:

One simply takes *arg and **kwarg as parameters and passes them directly on, with the asterisks attached.只需将*arg**kwarg作为参数并直接传递它们,并附上星号。 So in my case, to do my RPyC pass-through, where conn is the RPyC connection:所以在我的例子中,做我的 RPyC 直通,其中conn是 RPyC 连接:

def my_passthru(conn, function_name, *function_args, **function_kwargs):

    # Do a check of something or other here

    return_value = getattr(conn.root, function_name)(*function_args, **function_kwargs)

    # Do another check here

    return return_value

Then, for example, a call to my exposed_e() method above might be:然后,例如,对我上面的exposed_e()方法的调用可能是:

return_value = my_passthru(conn, e, thing1, thing2, thing3)

(the exposed_ prefix being added automagically by RPyC in this case). (在这种情况下,RPyC 自动添加了exposed_前缀)。

And of course one could put a try: / except ConnectionRefusedError: around the getattr() call in my_passthru() to generically catch the case where the connection has dropped underneath RPyC, which was my main purpose.当然,可以try: / except ConnectionRefusedError:my_passthru()中的getattr()调用周围,一般可以捕获连接在 RPyC 下掉线的情况,这是我的主要目的。

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

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