I am writing a context manager to wrap the builtins.print function. And this works fine. However I encountered a Python behaviour that I can't wrap my head around:
Whenever a classes' method is assigned into a variable for later calling, the first "self" argument seems to be automatically stored as well and used for all later calls.
Here's an example illustrating the point:
import functools
class Wrapper:
def wrap(self):
return self._wrapped #functools.partial(self._wrapped, self)
def _wrapped(self, *args, **kwargs):
print('WRAPPED!', *args, **kwargs)
print('..knows about self:', self)
wrapped = Wrapper().wrap()
wrapped('expect self here', 'but', 'get', 'all', 'output')
The output:
WRAPPED! expect self here but get all output
..knows about self: <__main__.Wrapper object at 0x2aaaab2d9f50>
Of course for normal functions (outside of classes) this magic does not happen. I can even assign that method in the example above directly without going through instantiation:
wrapped = Wrapper._wrapped
wrapped('expect self here', 'but', 'get', 'all', 'output')
And now I get what I first expected:
WRAPPED! but get all output
..knows about self: expect self here
In my original code, I used the functools.partial to curry-in the self, but then discovered that this is not even required.
I like the current behaviour, but I'm not yet understanding the reasoning with respect to consistency and "being obvious".
I'm working with Python 3.1.2 here.
Is this question with the answer to use types.MethodType related? Searching here and in the 'net largely results in basic info on currying/partial function calls and packing/unpacking of arg lists. Maybe I used inadequate search terms (e.g. "python currying methods".)
Can anyone shed some light into this behaviour?
Is this the same in Py2 and Py3?