A Guide to Python's Magic Methods (2012)
rszalski.github.io
rszalski.github.io
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...
AND I say this as someone who was reading peps going into 3's release.
Do Ubuntu or Fedora default to python 3 yet? Arch? My RHEL experience isn't as representative.
Core: 1
Extra: 96
Community: 822
AUR: Over 2300 depending on how you search
This is what every distro except arch does (for whatever reason)
https://access.redhat.com/documentation/en-us/red_hat_enterp...
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.
The thing is, it's also incredibly useful at times. Language features that are "useful when you have the use case for it, confusing when you don't" tend to provoke that reaction.
>>> dir(123)
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__',
'__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__',
'__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__',
'__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__',
'__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__',
'__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__',
'__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__',
'__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__',
'__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate',
'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']
>>> (1).__add__
<method-wrapper '__add__' of int object at 0x678C40A0>
>>> (123).__add__.__doc__
'Return self+value.'
>>> (1).__add__(2)
3
Which is a good thing, because it makes the whole arrangement a lot more consistent that languages in which this sort of thing is just magic associated with a specific primitive type (sometimes it's even inconsistent - e.g. in C#, + for ints and strings is magic, but + for decimal is an overloaded operator). In Python, all that magic is confined to the magic methods. Learn them once, and they work the same everywhere.I have just never done it before, and I think this is the first time I have seen the concept, so the first thing that popped in my mind we’re all the things that can go wrong. But, also all the things that can go right.
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.
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...
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.
https://www.agiliq.com/blog/2018/01/understanding-python-mag...
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.
if people think this is so magic, it's almost as if lisps, schemes, and prologs never existed.
I write quite a bit of Lisp, and the conclusion I've come to is that for 95% of software developers, Lisp, Scheme, and Prolog might as well not exist. Even here on HN, where I'd expect the bar to be a little higher, the amount of incorrect info posted about Lisp is pretty crazy.
I'm almost certain most people's only experience with Lisp(s) and Prolog was a week or two using it in their programming languages class at university.
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.
Its also for more complex stuff but then you have to grab additional libraries to do stuff like db management, migrations, serialization, etc.
Flask also has some, in my opinion, rather uncomfortablly unintuitive global scope stuff. Where responses aren't passed into the view function, they're available on the imported flask object.
I have made some really dynamic stuff (like 100 domains running off a single server with each of their data separate, and to add a new domain is a click away) . I can't imagine doing that with other frameworks
> get_attr
What the fuck is that?
Also, you might be interested in webpy
> “Django lets you write web apps in Django. TurboGears lets you write web apps in TurboGears. Web.py lets you write web apps in Python.” — Adam Atlas
When the interpreter exits, your program's resources should be reclaimed by the operating system, right? So why not just use __del__?
And in cases like the one cjhanks describes, __del__ doesn't get called reliably enough. In those cases, using a contextmanager is better.
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:
Search Engine: Python Docs
Keyword: py
URL: https://google.com/search?q=site:https://docs.python.org/3+%s&btnI
(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.,
py data model
in the URL and get the above page. Want the asyncio module docs? py asyncio
(I similarly have "mdn" for the developer.mozilla.org docs, which are also excellent.)