This post unfortunately reads like one of those Java programmer discovers Python (except not really) posts, but for C++. In general if you find yourself inventing a new paradigm for a 30-year old language you just started working with, it's reason enough to doubt you're doing something suboptimal. However, in this case the author is actually very familiar with Python, so I'm kinda confused.
<SomeGeometricObject>.area() is right AFAICS.
Which I think is what you're getting at anyway.
But IMO overloading used right is cleaner than not having overloading.
It's just putting the original area() function in a module, not making it a method of a class. It's the simplest solution you can have, ever.
Adding an object is already more complex, and complexity needs to be justified. Just KISS if you can.
Don't try to code in python like you code in another language.
Also, think about what your API is conveying. Overloading may make it less clear.
The snippet from this article is a good example of when not to do it:
Here, you have 2 functions that do 2 fundamentally different things. One is calculating an area for a circle. The other one is for a rectangle. When you have 2 different signatures, it's often a sign the process is very different, and you should signal that in your API.If you scan code using those, your brain cannot quickly parse it. It needs to process "area(), ok but of what, well, it has only x param, so I guess this is for z". The overloading gimmick has little value for the reader, but a real cost (not to mention in python it actually slows the run time)
The better solution is simply to make it explicitly 2 functions with good names:
Or, most likely, put them in separated namespaces (using a module or a class), which does the same. It's very easy to abuse overloading because it tickles our need for refactoring. But it's a tool to solve a problem, not an end by itself.