In Javascript, bind
, call
, and apply
allow you to change the reference to this
on demand. I'm looking at a situation in Python where the code would look a bit nicer if I were able to do this instead of using getattr
.
I'd like to pass a reference to a method, but change the instance the method refers to within a thread. In Javascript, I'd like to do this:
function produce (x) {
enqueue(this.api.delete.bind(this.api, x))
}
function consume () {
api = new API()
task = dequeue()
task.call(api)
}
In Python, I have to do this:
def produce(self, x):
enqueue(partial(self.api.delete, x))
def consume(self):
api = API()
task = dequeue() # callable
?????????
This may look a little odd, but what's going on is each api instance is running on a separate thread. getattr
works, but I would prefer to pass verbs instead of nouns to the queue.
You can enqueue a lambda closing over x
and waiting for its api
instance:
enqueue(lambda api: api.delete(x))
And later just pass the API object:
task = dequeue()
task(api)
You also can get an "unbound method reference" in Python 3, to which you can later pass self
, by simply naming the class member:
>>> 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, it will behave the same in Python 2, but the type of f
will be something special.)