[英]What is the most pythonic way to make a bound method act like a function?
I'm using a Python API that expects me to pass it a function. 我正在使用Python API,希望我将它传递给函数。 However, for various reasons, I want to pass it a method, because I want the function to behave different depending on the instance it belongs to.
但是,由于各种原因,我想传递一个方法,因为我希望函数的行为不同,具体取决于它所属的实例。 If I pass it a method, the API will not call it with the correct 'self' argument, so I'm wondering how to turn a method into a function that knows what 'self' it belongs to.
如果我传递一个方法,API将不会使用正确的'self'参数调用它,所以我想知道如何将方法转换为一个知道它属于'self'的函数。
There are a couple of ways that I can think of to do this, including using a lambda and a closure. 我可以想到有几种方法可以做到这一点,包括使用lambda和闭包。 I've included some examples of this below, but I'm wondering if there is a standard mechanism for achieving the same effect.
我在下面列举了一些这样的例子,但我想知道是否有一种达到同样效果的标准机制。
class A(object):
def hello(self, salutation):
print('%s, my name is %s' % (salutation, str(self)))
def bind_hello1(self):
return lambda x: self.hello(x)
def bind_hello2(self):
def hello2(*args):
self.hello(*args)
return hello2
>>> a1, a2 = A(), A()
>>> a1.hello('Greetings'); a2.hello('Greetings')
Greetings, my name is <__main__.A object at 0x71570>
Greetings, my name is <__main__.A object at 0x71590>
>>> f1, f2 = a1.bind_hello1(), a2.bind_hello1()
>>> f1('Salutations'); f2('Salutations')
Salutations, my name is <__main__.A object at 0x71570>
Salutations, my name is <__main__.A object at 0x71590>
>>> f1, f2 = a1.bind_hello2(), a2.bind_hello2()
>>> f1('Aloha'); f2('Aloha')
Aloha, my name is <__main__.A object at 0x71570>
Aloha, my name is <__main__.A object at 0x71590>
Will passing in the method bound to a instance work? 将绑定到实例的方法传入工作吗? If so, you don't have to do anything special.
如果是这样,您不必做任何特别的事情。
In [2]: class C(object):
...: def method(self, a, b, c):
...: print a, b, c
...:
...:
In [3]: def api_function(a_func):
...: a_func("One Fish", "Two Fish", "Blue Fish")
...:
...:
In [4]: c = C()
In [5]: api_function(c.method)
One Fish Two Fish Blue Fish
You may want to clarify your question. 您可能想澄清您的问题。 As Ryan points out,
正如瑞恩指出的那样,
def callback(fn):
fn('Welcome')
callback(a1.hello)
callback(a2.hello)
will result in hello
being called with the correct self
bound, a1
or a2
. 将导致使用正确的
self
绑定, a1
或a2
调用hello
。 If you are not experiencing this, something is deeply wrong, because that's how Python works. 如果您没有遇到这种情况,那么就会出现严重错误,因为这就是Python的工作方式。
What you seem to want, judging by what you've written, is to bind arguments -- in other words, currying . 你似乎什么希望,通过你写的判断,是绑定参数-换句话说, 哗众取宠 。 You can find examples all over the place, but Recipe 52549 has the best Pythonic appearance, by my tastes.
你可以找到各地的例子,但根据我的口味, 食谱52549具有最佳的Pythonic外观。
class curry:
def __init__(self, fun, *args, **kwargs):
self.fun = fun
self.pending = args[:]
self.kwargs = kwargs.copy()
def __call__(self, *args, **kwargs):
if kwargs and self.kwargs:
kw = self.kwargs.copy()
kw.update(kwargs)
else:
kw = kwargs or self.kwargs
return self.fun(*(self.pending + args), **kw)
f1 = curry(a1.hello, 'Salutations')
f1() # == a1.hello('Salutations')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.