They're also not as well documented as they need to be. All of
the magic methods for Python appear in the same section in the
Python docs, but they're scattered about and only loosely organized.
[end quote]
You got that? They're all in the same section, AND they are scattered
about at the same time! Now that's truly magic! *wink*
Special is not magic. Magic means that the normal behaviour of the
language is broken for some arbitrary cases. Here's an example in
hardware of "magic":
http://catb.org/jargon/html/magic-story.html
Now imagine that in software: it can't possibly work, and yet it does.
I dare say nearly all non-toy languages have *some* magic. But some
languages have more than others: they are full of unique cases, every one
different, where the same code behaves differently that you would expect.
There *is* some magic in Python:
* Methods and attributes that start with a double underscore, but do not
end with a double underscore, have their name mangled by the compiler.
So your source code says "MyClass.__method", but the method actually
created is "MyClass.__MyClass_method".
This is magic because __names everywhere else do not work that way,
nor do names that don't start with double-underscores.
* In Python 3, if you call super() with no arguments inside a class,
the compiler runs some voodoo to determine the class it belongs to
and the instance it is called from. Outside of a class, super()
with no arguments behaves like any other function.
This is magic because the normal behaviour of a function with two
required arguments is to fail if you don't provide the arguments.
But super() can, somehow, determine the arguments itself, partially
at compile-time and partially at run-time.
* The relationship between built-ins type() and object() is magic.
object is a type. But type is itself an object. You can't define
object until type exists, and you can't define type until object
exists. But the compiler magically bootstraps them into existence.
This is magic because it is impossible[2] for pure Python code to
bootstrap such mutually-defined types into existence.
Off the top of my head, I can't really think of anything else that is
magic in Python.
Note that individual uses of magic are generally done for good reasons,
or at least what seems like a good reason. For example, super's magic
class detection is useful and prevents bugs. But *in general* magic is a
bad thing, because it makes the language incomprehensible and code
surprising. Languages with a lot of magic tend towards code which is hard
to maintain and debug.
Note also that "magic" is different from "deep magic" and "black magic":
http://catb.org/jargon/html/M/magic.html
[1] Perhaps not quite *nothing*, arguably there is a *tiny* bit of magic
in that Python bypasses the instance when looking up __dunder__ methods
as a speed optimization. But that's more like a sprinkle of fairy dust
than real magic.
[2] Or at least tricky and messy.