🕵🏽 Investigating python Callables : functions, methods and more…

🕵🏽 Investigating python Callables : functions, methods and more…

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.

Leave a Reply

Your email address will not be published. Required fields are marked *