Класс Python наследует объект

Есть ли причина для объявления класса наследовать от object?

Я только что нашел код, который делает это, и я не могу найти вескую причину, почему.

class MyClass(object):
    # class code follows...

6 ответов

Решение

Есть ли причина для объявления класса наследовать от object?

tl; dr: В Python 3, кроме совместимости между Python 2 и 3, нет причин. В Python 2 много причин.


История Python 2.x:

В Python 2.x (начиная с 2.2) есть два стиля классов в зависимости от наличия или отсутствия object в качестве базового класса:

  1. классические классы стиля: у них нет object в качестве базового класса:

    >>> class ClassicSpam:      # no base class
    ...     pass
    >>> ClassicSpam.__bases__
    ()
    
  2. "новые" классы стилей: они имеют, прямо или косвенно (например, наследуют от встроенного типа), object в качестве базового класса:

    >>> class NewSpam(object):           # directly inherit from object
    ...    pass
    >>> NewSpam.__bases__
    (<type 'object'>,)
    >>> class IntSpam(int):              # indirectly inherit from object...
    ...    pass
    >>> IntSpam.__bases__
    (<type 'int'>,) 
    >>> IntSpam.__bases__[0].__bases__   # ... because int inherits from object  
    (<type 'object'>,)
    

Без сомнения, при написании класса вы всегда захотите перейти на классы нового стиля. Преимущества в этом многочисленны, чтобы перечислить некоторые из них:

  • Поддержка дескрипторов. В частности, следующие дескрипторы стали возможными с помощью дескрипторов:

    1. classmethod: Метод, который получает класс в качестве неявного аргумента вместо экземпляра.
    2. staticmethod: Метод, который не получает неявный аргумент self в качестве первого аргумента.
    3. свойства с property: Создать функции для управления получением, установкой и удалением атрибута.
    4. __slots__ Сохраняет потребление памяти классом, а также ускоряет доступ к атрибутам. Конечно, это накладывает ограничения.
  • __new__ Статический метод: позволяет настроить способ создания новых экземпляров классов.

  • Порядок разрешения методов (MRO): в каком порядке будут искать базовые классы класса при попытке определить, какой метод вызывать.

  • Связанные с MRO, super звонки. Также см, super() считается супер.

Если вы не наследуете от object забудь это. Более исчерпывающее описание предыдущих пунктов маркировки наряду с другими преимуществами "новых" классов стилей можно найти здесь.

Одним из недостатков классов нового стиля является то, что сам класс требует больше памяти. Если, конечно, вы не создаете много объектов класса, я сомневаюсь, что это будет проблемой, и это будет негативное погружение в море позитива.


История Python 3.x:

В Python 3 все упрощено. Существуют только классы нового стиля (называемые просто классами), поэтому единственная разница в добавлении object требует от вас ввести еще 8 символов. Это:

class ClassicSpam:
    pass

полностью эквивалентен (кроме их имени:-) этому:

class NewSpam(object):
     pass

и к этому:

class Spam():
    pass

у всех есть object в их __bases__,

>>> [object in cls.__bases__ for cls in {Spam, NewSpam, ClassicSpam}]
[True, True, True]

Итак, что нужно делать?

В Python 2: всегда наследовать от object явно. Получи льготы.

В Python 3: наследовать от object если вы пишете код, который пытается быть независимым от Python, то есть он должен работать как в Python 2, так и в Python 3. В противном случае это не имеет никакого значения, поскольку Python вставляет его вам за кулисы.

Python 3.x:
class MyClass(object): = новый стиль
class MyClass: = новый стиль класса (неявно наследуется от объекта)

Python 2.x:
class MyClass(object): = новый стиль
class MyClass: = СТАРЫЙ СТИЛЬ КЛАСС

Объяснение:

При определении базовых классов в Python 3.x вы можете удалить объект из определения. Тем не менее, это может открыть дверь для серьезного трудно отследить проблему...

Python представил классы нового стиля еще в Python 2.2, и к настоящему времени классы старого стиля действительно довольно старые. Обсуждение классов в старом стиле скрыто в документах 2.x и отсутствует в документах 3.x.

Проблема в том, что синтаксис для классов старого стиля в Python 2.x такой же, как и альтернативный синтаксис для классов нового стиля в Python 3.x. Python 2.x по-прежнему очень широко используется (например, GAE, Web2Py), и любой код (или кодер), невольно вносящий определения классов в стиле 3.x в код 2.x, в конечном итоге будет иметь некоторые серьезно устаревшие базовые объекты. А поскольку классы старого стиля ни на чём не находятся, они, вероятно, не будут знать, что их поразило.

Так что просто разберитесь в этом долгий путь и сэкономьте разработчику 2.x слезы.

Да, это объект "нового стиля". Это была особенность, представленная в python2.2.

Новые объекты стиля имеют объектную модель, отличную от классических объектов, и некоторые вещи не будут работать должным образом со старыми объектами стиля, например, super(), @property и дескрипторы. Смотрите эту статью для хорошего описания того, что новый класс стиля.

Так что ссылка для описания различий: В чем разница между старым стилем и новым стилем классов в Python?

История от изучения Python трудный путь:

Оригинальное представление Python класса было сломано во многих серьезных отношениях. К тому времени, когда эта ошибка была признана, было уже слишком поздно, и они должны были поддержать это. Чтобы решить проблему, им нужен был стиль "новый класс", чтобы "старые классы" продолжали работать, но вы можете использовать новую, более правильную версию.

Они решили, что они будут использовать слово "объект" в нижнем регистре, чтобы быть "классом", от которого вы наследуете, чтобы создать класс. Это сбивает с толку, но класс наследует от класса с именем "объект", чтобы создать класс, но на самом деле это не объект, а класс, но не забудьте наследовать от объекта.

Кроме того, просто чтобы вы знали, в чем разница между классами нового стиля и классами старого стиля, это то, что классы нового стиля всегда наследуются от object класс или из другого класса, который унаследован от object:

class NewStyle(object):
    pass

Другой пример:

class AnotherExampleOfNewStyle(NewStyle):
    pass

Хотя базовый класс старого стиля выглядит так:

class OldStyle():
    pass

И дочерний класс старого стиля выглядит так:

class OldStyleSubclass(OldStyle):
    pass

Вы можете видеть, что базовый класс старого стиля не наследуется ни от какого другого класса, однако классы старого стиля могут, конечно, наследовать друг от друга. Наследование от объекта гарантирует, что определенная функциональность доступна в каждом классе Python. Новые классы стиля были введены в Python 2.2

Да, это исторически. Без этого он создает класс в старом стиле.

Если вы используете type() на объекте старого стиля вы просто получаете "экземпляр". На объекте нового стиля вы получаете его класс.

Синтаксис оператора создания класса:

class <ClassName>(superclass):
    #code follows

В отсутствие каких-либо других суперклассов, от которых вы конкретно хотите наследовать, superclass всегда должен быть object, который является корнем всех классов в Python.

object технически является корнем классов "нового стиля" в Python. Но классы нового стиля сегодня так же хороши, как и единственный стиль занятий.

Но, если вы явно не используете слово object при создании классов, как уже упоминалось, Python 3.x неявно наследуется от object суперкласс. Но я думаю, что явное всегда лучше, чем неявное (ад)

Ссылка

Это создает новый стиль класса.

Другие вопросы по тегам