The way python handles functions is a bit unique and the star โญ of the show is the "self" argument passed to every function defined within a class, But have you ever wondered, how self is passed to the function? We never pass it during the call.
How does it get there ? and how can we replicate it ?
Well in this article, we will try to understand and replicate it. Lets put the fun in functions
๐.
๐งฉ Types of functions in Python.
First, we need to understand is the type
of functions. When using mypy, we annotate them as a Callable but that is not a python standard type. To figure this out lets get coding.
(I know that world is spelt wrong, GET OFF MY BACK)
Running the above code gives us the following results.
<class 'function'>
A bit anticlimactic, so a function is of type function
, what about methods (foreshadowing...) or functions within a classes ?
Running the following code gives us a bit more idea. The Output shows us
<bound method Foo.foo of <__main__.Foo object at 0x0000020B6B999D00>>
<class 'method'>
<function Foo.foo at 0x0000020B6B9B91C0>
We learn 3 things from this.
- The type of a function belonging to a class is
method
- The reference of a method is a
bound method
tied down to the instance. - Interestingly, a
method
on a class level is treated as a function.
๐คจ How does self get there ?
When an instance of a class is created, the functions defined within them get replaced by descriptors, with the instance passed to them as the first argument.
You can learn more about descriptors from here. The TLDR is, that they are getter and setters for instance attributes.
Try the following code and see what happens ๐คฉ
Checking the type of the function, reveals a funny thing. The type of the bar function has been changed to a method
and is bound to the int object 10.
๐ค What if you don't want a bound method ?
In the above example, We create a bound method to tie some arguments to the function. What if you don't want to do that ? What if you don't want to use the get method ? How can we recreate the above functionality, Well we use decorators !!!!!.
If you don't want to use the decorator synthetic sugar, you can use this.
๐ One more thing.
Like we saw above methods
are defined as a function
type at the class level. Which means the first argument is unbound and we can do this.
๐ Conclusion
Thanks for following this article and hope you learned something new about functions in python. Word of caution, don't use this in production level code, unless you want to annoy your co-workers, if so, go crazy.
Just cause we could to these shenanigans, doesn't mean we should.
Top comments (0)