Why does Python use 'magic methods'?

后端 未结 7 1658
既然无缘
既然无缘 2020-11-29 16:56

I\'ve been playing around with Python recently, and one thing I\'m finding a bit odd is the extensive use of \'magic methods\', e.g. to make its length available, an object

7条回答
  •  迷失自我
    2020-11-29 17:40

    While the reason is mostly historic, there are some peculiarities in Python's len that make the use of a function instead of a method appropriate.

    Some operations in Python are implemented as methods, for example list.index and dict.append, while others are implemented as callables and magic methods, for example str and iter and reversed. The two groups differ enough so the different approach is justified:

    1. They are common.
    2. str, int and friends are types. It makes more sense to call the constructor.
    3. The implementation differs from the function call. For example, iter might call __getitem__ if __iter__ isn't available, and supports additional arguments that don't fit in a method call. For the same reason it.next() has been changed to next(it) in recent versions of Python - it makes more sense.
    4. Some of these are close relatives of operators. There's syntax for calling __iter__ and __next__ - it's called the for loop. For consistency, a function is better. And it makes it better for certain optimisations.
    5. Some of the functions are simply way too similar to the rest in some way - repr acts like str does. Having str(x) versus x.repr() would be confusing.
    6. Some of them rarely use the actual implementation method, for example isinstance.
    7. Some of them are actual operators, getattr(x, 'a') is another way of doing x.a and getattr shares many of the aforementioned qualities.

    I personally call the first group method-like and the second group operator-like. It's not a very good distinction, but I hope it helps somehow.

    Having said this, len doesn't exactly fit in the second group. It's more close to the operations in the first one, with the only difference that it's way more common than almost any of them. But the only thing that it does is calling __len__, and it's very close to L.index. However, there are some differences. For example, __len__ might be called for the implementation of other features, such as bool, if the method was called len you might break bool(x) with custom len method that does completely different thing.

    In short, you have a set of very common features that classes might implement that might be accessed through an operator, through a special function (that usually does more than the implementation, as an operator would), during object construction, and all of them share some common traits. All the rest is a method. And len is somewhat of an exception to that rule.

提交回复
热议问题