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

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

1009 голосов
/ 25 октября 2010

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

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

Ответы [ 6 ]

519 голосов
/ 12 июля 2017

Есть ли причина для объявления класса наследоваться от 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 вставляет его вам за кулисы.

514 голосов
/ 26 февраля 2012

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 от слез.

397 голосов
/ 25 октября 2010

Да, это объект «нового стиля». Это была функция, представленная в python2.2.

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

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

30 голосов
/ 04 ноября 2014

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

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

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

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

class NewStyle(object):
    pass

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

class AnotherExampleOfNewStyle(NewStyle):
    pass

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

class OldStyle():
    pass

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

class OldStyleSubclass(OldStyle):
    pass

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

28 голосов
/ 25 октября 2010

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

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

6 голосов
/ 20 октября 2016

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

class <ClassName>(superclass):
    #code follows

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

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

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

Ссылка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...