Использование len() и def __len__(self): для создания класса

Просто любопытно,

Есть ли разница (преимущества и недостатки) между использованием len() или же def __len__() когда я строю класс? И какой стиль Python лучший?

   class foo(object):
      def __init__(self,obs=[])
         self.data = obs
         self.max = max(obs)
         self.min = min(obs)
         self.len = len(obs)

или же

   class foo(object):
      def __init__(self,obs=[])
         self.data = obs
         self.max = max(obs)
         self.min = min(obs)
      def __len__(self):
         return len(self.data)

2 ответа

Решение

Существует огромная разница.

__len__() Метод является методом ловушки. len() функция будет использовать __len__ метод, если присутствует, чтобы запросить у вашего объекта его длину.

Нормальный API, который люди ожидают использовать - это len() метод, используя .len Атрибут вместо этого будет отклоняться от этой нормы.

Если длина self.data не ожидается изменения, вы всегда можете кэшировать длину в атрибуте и иметь .__len__() вернуть этот атрибут.

class foo(object):
    def __init__(self, obs=None):
        if obs is None:  # provide a default if no list was passed in.
            obs = []
        self.data = obs
        self.max = max(obs)
        self.min = min(obs)
        self._data_len = len(obs)

    def __len__(self):
        return self._data_len

Есть несколько отличий:

  1. Только второй подход даст вам знакомый len(obj) синтаксис для foo, Первый потребует obj.len(),
  2. Если длина self.data может изменить пост-конструкцию, только вторая версия будет отражать новую длину.
Другие вопросы по тегам