It's amazing that Python 3 was 4 years old when this post was made and yet saying "Python" was still implicitly assumed by basically everyone to mean 2.x.
> Once you know this stuff, you'll be a much stronger debugger.
As you suggest, more accurately, you'll require the next person who debugs your code to read this, making them much better at debugging your code.
I no longer use magic and completely avoid meta programming in python. It confuses everyone, is not needed (just use a boring factory function), and severely limits who can help you work on your code, for what? A few lines of less boilerplate here and there? "Succinctness"? Some sort of "elegance"? More likely, a DSL that nobody understands but you!
The more I write, and mostly the more I interact with other people, the more I realize that code needs to be boring. No magic. I think this is why go is succeeding: no magic.
My reaction to this, as someone who doesn’t use many of these on a regular basis (probably guilty of overusing __new__ though) is actually that I can imagine these causing some real problems. The operator ones seem particularly tempting and dangerous at the same time.
Could you give an example of how you would use these methods to debug versus other methods/approaches? I'd love to hear if you're willing to share--I program mainly in Python these days but Python's magic methods are definitely something I need to understand at a deeper level.
A related article I got a lot out of was ‘Understanding Python Metaclasses’, an in-depth breakdown of Python class instantiation. Here’s the link to that:
It's awesome that someone has taken the time to write this all up. With reference to this section (https://rszalski.github.io/magicmethods/#descriptor) the author mentions that descriptors are "meant to be held by an owner class." which is true, however in their example, they are storing the value as `self.value` on the descriptor object itself meaning that if the user were to have two instances of `Distance` all their values would be the same for meter or foot on all instances of `Distance`. One way to solve this is to store the values in a dictionary-like structure on the descriptor, e.g. `self.data[instance] = your_stored_value`.
Django's DRY suuuuuuuucks when you're getting started. It's basically all this magic that you can't understand without already knowing Django.
Why does get_attr get called? Oh because it begins with the word "get" and there's an attribute that defines a method field called "attr".
I use Django a lot and generally it's great. But I hate that you can't follow your code paths from start to finish on the surface. You have to know about how it works underneath. Meaning you can't just be a python + web server expert. You have to also be a Django expert. So I get non-Django experts reviewing code and they have no clue why things work or break.
Just an opinion. Not saying this is objectively wrong.
But this article is just explaining operator overloading, right? Doesn't everyone learn that halfway through semester in C++ 101?
And operator overloading has nothing to do with DRY, in fact it's generally better to avoid it except for in very niche situations, like adding __add__ to a matrix type.
> Be careful, however, as there is no guarantee that __del__ will be executed if the object is still alive when the interpreter exits, so __del__ can't serve as a replacement for good coding practices (like always closing a connection when you're done with it.
When the interpreter exits, your program's resources should be reclaimed by the operating system, right? So why not just use __del__?
You almost always only want to implement __del__ if you're writing an extension in C. Otherwise, the GC generally takes care of cleanup perfectly fine.
And in cases like the one cjhanks describes, __del__ doesn't get called reliably enough. In those cases, using a contextmanager is better.
If this were the case, there would be no need for SIGTERM. The OS doesn't know the application logic and can't guarantee clean termination from the application's perspective.
As others have said, there's rarely reason to override `__del__`, and when you do you know exactly why you need it.
(The article will perhaps be a better guide to those newer; the data model page is … pretty dense.)
Also, I find is exceptionally handy to have a Chrome "search engine" for the Python docs while I work. That is, on chrome://settings/searchEngines I have added a custom search engine with this setup:
[+] [-] montecarl|7 years ago|reply
In Python 3 __cmp__ is ignored and you have to use the other methods. To make this easier, you can use https://docs.python.org/3/library/functools.html#functools.t...
[+] [-] gvx|7 years ago|reply
[+] [-] opencl|7 years ago|reply
[+] [-] kqr|7 years ago|reply
But it's also worth throwing a warning out there: when you first learn about a new type of magic, you'll be tempted to use it everywhere. Be careful!
I can recognise a clear specific period in my Python work which was just after I had read this, and a bunch of things suddenly became implicit.
[+] [-] nomel|7 years ago|reply
As you suggest, more accurately, you'll require the next person who debugs your code to read this, making them much better at debugging your code.
I no longer use magic and completely avoid meta programming in python. It confuses everyone, is not needed (just use a boring factory function), and severely limits who can help you work on your code, for what? A few lines of less boilerplate here and there? "Succinctness"? Some sort of "elegance"? More likely, a DSL that nobody understands but you!
The more I write, and mostly the more I interact with other people, the more I realize that code needs to be boring. No magic. I think this is why go is succeeding: no magic.
[+] [-] florabuzzword|7 years ago|reply
[+] [-] Puer|7 years ago|reply
[+] [-] florabuzzword|7 years ago|reply
A related article I got a lot out of was ‘Understanding Python Metaclasses’, an in-depth breakdown of Python class instantiation. Here’s the link to that:
https://blog.ionelmc.ro/2015/02/09/understanding-python-meta...
[+] [-] pypypypypypy|7 years ago|reply
[+] [-] devxpy|7 years ago|reply
It's absolutely bonkers the extent to which you can be dynamic in this language.
It's the very reason why Django is so DRY.
[+] [-] Waterluvian|7 years ago|reply
Why does get_attr get called? Oh because it begins with the word "get" and there's an attribute that defines a method field called "attr".
I use Django a lot and generally it's great. But I hate that you can't follow your code paths from start to finish on the surface. You have to know about how it works underneath. Meaning you can't just be a python + web server expert. You have to also be a Django expert. So I get non-Django experts reviewing code and they have no clue why things work or break.
Just an opinion. Not saying this is objectively wrong.
[+] [-] nikofeyn|7 years ago|reply
if people think this is so magic, it's almost as if lisps, schemes, and prologs never existed.
[+] [-] sbjs|7 years ago|reply
And operator overloading has nothing to do with DRY, in fact it's generally better to avoid it except for in very niche situations, like adding __add__ to a matrix type.
[+] [-] misiti3780|7 years ago|reply
[+] [-] olooney|7 years ago|reply
[+] [-] saagarjha|7 years ago|reply
When the interpreter exits, your program's resources should be reclaimed by the operating system, right? So why not just use __del__?
[+] [-] gvx|7 years ago|reply
And in cases like the one cjhanks describes, __del__ doesn't get called reliably enough. In those cases, using a contextmanager is better.
[+] [-] cjhanks|7 years ago|reply
[+] [-] pfranz|7 years ago|reply
[+] [-] lstyls|7 years ago|reply
As others have said, there's rarely reason to override `__del__`, and when you do you know exactly why you need it.
[+] [-] falsedan|7 years ago|reply
[+] [-] jl2718|7 years ago|reply
[+] [-] deathanatos|7 years ago|reply
(The article will perhaps be a better guide to those newer; the data model page is … pretty dense.)
Also, I find is exceptionally handy to have a Chrome "search engine" for the Python docs while I work. That is, on chrome://settings/searchEngines I have added a custom search engine with this setup:
(The URL is an "I'm feeling lucky" search on Google, limited to the Python 3 docs. Note that it is set to search Python 3.)This allows me to type, e.g.,
in the URL and get the above page. Want the asyncio module docs? (I similarly have "mdn" for the developer.mozilla.org docs, which are also excellent.)[+] [-] meowface|7 years ago|reply