在Javascript中,bind
,call
和apply
允许您根据需要更改对this
的引用。我正在研究Python中的情况,如果我能够执行此操作而不是使用getattr
,代码看起来会更好。
我想传递对方法的引用,但是更改方法在线程中引用的实例。在Javascript中,我想这样做:
function produce (x) {
enqueue(this.api.delete.bind(this.api, x))
}
function consume () {
api = new API()
task = dequeue()
task.call(api)
}
在Python中,我必须这样做:
def produce(self, x):
enqueue(partial(self.api.delete, x))
def consume(self):
api = API()
task = dequeue() # callable
?????????
这可能看起来有点奇怪,但是发生的事情是每个api实例都在一个单独的线程上运行。 getattr
有效,但我更愿意将动词而不是名词传递给队列。
答案 0 :(得分:2)
您可以将lambda排队等候x
并等待其api
个实例:
enqueue(lambda api: api.delete(x))
稍后只需传递API对象:
task = dequeue()
task(api)
您还可以获得"未绑定的方法参考"在Python 3中,您可以稍后通过简单命名类成员来传递self
:
>>> class A:
... def foo(self, x):
... print(x)
...
>>> f = A.foo
>>> f(A(), 1) # equivalent to A().foo(1)
1
>>> f
<function A.foo at 0x7f86c9b872f0>
(IIRC,它在Python 2中的行为相同,但f
的类型将是特别的。)
答案 1 :(得分:2)
与phg的答案相关(OK,基本相同),operator
模块提供methodcaller
函数,该函数采用方法名称(以及可选的方法参数)和返回一个新的可调用对象,当使用对象调用时,使用给定的参数调用对象上的命名方法。
from operator import methodcaller
# methodcaller('foo', arg1)(thing) == thing.foo(arg1)
def produce(self, x):
enqueue(methodcaller('delete', x))
def consume(self):
api = API()
task = dequeue() # callable
task(api)