Часто случается, что «типичным» поведением встроенного оператора или оператора является вызов (с другим и более приятным синтаксисом) подходящих магических методов (с именами, такими как __whatever__
) для задействованных объектов. Часто встроенный оператор или оператор имеет «добавленную стоимость» (он может выбирать различные пути в зависимости от задействованных объектов) - в случае len
против __len__
это всего лишь небольшая проверка работоспособности встроенного в том, что отсутствует в магическом методе:
>>> class bah(object):
... def __len__(self): return "an inch"
...
>>> bah().__len__()
'an inch'
>>> len(bah())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object cannot be interpreted as an integer
Когда вы видите вызов встроенного len
, вы уверены , что, если программа продолжит работу после этого, а не вызовет исключение, вызов вернет целое число, не отрицательно, и меньше 2 ** 31 - когда вы видите вызов xxx.__len__()
, у вас нет уверенности (за исключением того, что автор кода либо незнаком с Python, либо не очень хорошо; -).
Другие встроенные функции обеспечивают еще большую ценность, помимо простых проверок работоспособности и читабельности. Благодаря единой разработке всего Python для работы через вызовы встроенных функций и использование операторов, а не через вызовы магических методов, программисты избавляются от бремени запоминания того, какой случай есть какой. (Иногда появляется ошибка: до 2.5 вам нужно было вызвать foo.next()
- в 2.6, хотя это все еще работает для обратной совместимости, вы должны вызвать next(foo)
, а в 3.*
магический метод правильно назван __next__
вместо "упс-эй" next
! -).
Таким образом, общее правило должно заключаться в том, чтобы никогда не вызывать магический метод напрямую (но всегда косвенно через встроенный), если вы точно не знаете, зачем вам это нужно (например, когда вы переопределяете такой метод в подклассе). , если подкласс должен отложить до суперкласса, что должно быть сделано посредством явного вызова магического метода).