Please look at the simple example:
class A: def __init__(self, flag): self.flag = flag def func(self): print self.flag a = A(1) b = A(2) callback_a = a.func callback_b = b.func callback_a() callback_b()
The result is:
1 2
It runs as expected. But I have a question. In C, the callback function is passed as a pointer. In Python, it should have a similar way to do this, so the caller knows the address of the function. But in my example, not only the function pointer is passed, but also the parameter (self) is passed, because the same method of the same class prints different results. So my questions are:
Does such a method in Python only has one copy in memory? My meaning is that the code of any method only has one copy, and in my example the method won't be cloned itself. I think it should have only one copy, but here I still make this question in order to get more inputs.
I remember everything in Python is an object. So in my example, are there two function instances with different parameters but only one copy of code?
In Python, a callback is simply a function or a method passed to LocalSolver. A callback takes two parameters: the LocalSolver object that triggers the event and the type of the callback. It is possible to use the same callback method or object for multiple events or multiple LocalSolver instances.
A callback function is a function passed into another function as an argument, which is then invoked inside the outer function to complete some kind of routine or action. The above example is a synchronous callback, as it is executed immediately.
The main difference between a normal function and a callback function can be summarized as follows: A normal function is called directly, while a callback function is initially only defined. The function is only called and executed once a specific event has occurred.
The __call__ method enables Python programmers to write classes where the instances behave like functions and can be called like a function. When the instance is called as a function; if this method is defined, x(arg1, arg2, ...) is a shorthand for x.
In Python, the callback is not simply a reference to a member function. Instead, it is "bound" to the object that it refers to when it was created. So a.func
creates a callable that is bound to a
, and b.func
creates a callable that is bound to b
.
Python only needs one implementation of func()
in memory, but it will probably create one or more "trampoline" functions at runtime to accomplish the binding (I'm not certain of the internal details on this, and it would differ between Python implementations anyway).
If you print id(callback_a)
and id(callback_b)
you will get different results, showing that they are indeed different callable objects.
Specific to CPython, there is only one copy of the function object. During instance creation, the class wraps the unbound functions in its namespace as bound methods. But they all wrap the same function.
Here's your example expanded to show what's going on.
class A(object): def __init__(self, flag): self.flag = flag def func(self): print self.flag a = A(1) b = A(2) callback_a = a.func callback_b = b.func print "typeof(callback_a) = {0}".format(type(callback_a)) print "typeof(callback_b) = {0}".format(type(callback_b)) print "typeof(callback_a.__func__) = {0}".format(type(callback_a.__func__)) print "typeof(callback_b.__func__) = {0}".format(type(callback_b.__func__)) print "'callback_a.__func__ is callback_b.__func__' is {0}".format(callback_a.__func__ is callback_b.__func__) callback_a() callback_b()
This code outputs
typeof(callback_a) = <type 'instancemethod'> typeof(callback_b) = <type 'instancemethod'> typeof(callback_a.__func__) = <type 'function'> typeof(callback_b.__func__) = <type 'function'> 'callback_a.__func__ is callback_b.__func__' is True
You can clearly see, using the is
operator, that both instancemethod
classes are sharing the same function object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With