Хотя причина в основном историческая, в 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()
применяется только к последовательностям и т. Д.