Хотя причина в основном историческая, в Python len
есть некоторые особенности, которые делают использование функции вместо метода подходящим.
Некоторые операции в Python реализованы как методы, например list.index
и dict.append
, в то время как другие реализованы как вызываемые и магические методы, например str
и iter
и reversed
. Две группы достаточно различаются, поэтому оправдан разный подход:
- Они распространены.
str
, int
и друзья являются типами. Имеет больше смысла вызывать конструктор.
- Реализация отличается от вызова функции. Например,
iter
может вызвать __getitem__
, если __iter__
недоступен, и поддерживает дополнительные аргументы, которые не вписываются в вызов метода. По той же причине it.next()
был изменен на next(it)
в последних версиях Python - это имеет больше смысла.
- Некоторые из них являются близкими родственниками операторов. Существует синтаксис для вызова
__iter__
и __next__
- он называется циклом for
. Для согласованности, функция лучше. И это делает его лучше для определенных оптимизаций.
- Некоторые функции просто слишком похожи на остальные -
repr
действует так же, как str
. Наличие str(x)
против x.repr()
может привести к путанице.
- Некоторые из них редко используют фактический метод реализации, например
isinstance
.
- Некоторые из них являются действительными операторами,
getattr(x, 'a')
- это еще один способ сделать x.a
, и getattr
разделяет многие из вышеупомянутых качеств.
Лично я называю метод первой группы подобным, а оператор второй - подобным. Это не очень хорошее различие, но я надеюсь, что это как-то поможет.
Сказав это, len
не совсем вписывается во вторую группу. Он ближе к операциям в первом, с той лишь разницей, что он более распространен, чем почти любой из них. Но единственное, что он делает, это вызывает __len__
, и это очень близко к L.index
. Однако есть некоторые отличия. Например, __len__
может быть вызван для реализации других функций, таких как bool
, если метод был вызван len
, вы могли бы сломать bool(x)
с помощью пользовательского len
метода, который делает совершенно другую вещь. *
Короче говоря, у вас есть набор очень общих функций, которые могут реализовывать классы, к которым можно получить доступ через оператор, через специальную функцию (которая обычно делает больше, чем реализация, как оператор), во время конструирования объекта и все они имеют некоторые общие черты. Все остальное - это метод. И len
является чем-то вроде исключения из этого правила.