Хотя причина в основном историческая, в Python есть некоторые особенности, lenиз-за которых уместным является использование функции вместо метода.
Некоторые операции в Python реализованы как методы, например , list.indexи dict.append, в то время как другие реализуются как и магические вызываемые объекты методы, например , strи iterи reversed. Эти две группы достаточно различаются, поэтому разный подход оправдан:
- Они обычные.
str, intа друзья - типы. Имеет смысл вызвать конструктор.
- Реализация отличается от вызова функции. Например,
iterможет вызывать, __getitem__если __iter__он недоступен, и поддерживает дополнительные аргументы, которые не подходят для вызова метода. По той же причине в последних версиях Python it.next()был изменен на next(it)- это имеет больше смысла.
- Некоторые из них - близкие родственники операторов. Есть синтаксис для вызова
__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это своего рода исключение из этого правила.
len()илиreversed()применимое ко многим типам объектов, но такой методappend()применяется только к последовательностям и т. Д.