Есть ли причина, по которой объявление класса должно наследовать от object
?
Я только что нашел код, который делает это, и я не могу найти вескую причину.
class MyClass(object):
# class code follows...
Есть ли причина, по которой объявление класса должно наследовать от object
?
Я только что нашел код, который делает это, и я не могу найти вескую причину.
class MyClass(object):
# class code follows...
Есть ли какая-либо причина для объявления класса наследоваться от
object
?
В Python 3, кроме совместимости между Python 2 и 3, нет причин. В Python 2 много причин.
В Python 2.x (начиная с 2.2 и далее) существует два стиля классов в зависимости от наличия или отсутствия object
в качестве базового класса:
классы в "классическом" стиле: у них нет object
в качестве базового класса:
>>> class ClassicSpam: # no base class
... pass
>>> ClassicSpam.__bases__
()
классы "нового" стиля: они имеют, прямо или косвенно (например, наследуют от встроенного типа), 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'>,)
Без сомнения, при написании класса вы всегда захотите перейти на классы нового стиля. Преимущества этого многочисленны, перечислим некоторые из них:
Поддержка дескрипторов. В частности, следующие дескрипторы стали возможными с помощью дескрипторов:
classmethod
: метод, который получает класс в качестве неявного аргумента вместо экземпляра.staticmethod
: метод, который не получает неявный аргумент self
в качестве первого аргумента.property
: создание функций для управления получением, установкой и удалением атрибута.__slots__
: экономит потребление памяти классом, а также ускоряет доступ к атрибутам. Конечно, это накладывает ограничения.Статический метод __new__
: позволяет настроить создание новых экземпляров классов.
Порядок разрешения методов (MRO): в каком порядке будут искать базовые классы класса при попытке определить, какой метод вызывать.
В связи с MRO super
вызывает. Также смотрите, super()
считается супер.
Если вы не наследуете от object
, забудьте об этом. Более полное описание предыдущих пунктов маркировки наряду с другими преимуществами "новых" классов стилей можно найти здесь.
Одним из недостатков классов нового стиля является то, что сам класс требует больше памяти. Если, конечно, вы не создаете много объектов класса, я сомневаюсь, что это будет проблемой, и это будет негативное погружение в море позитива.
В 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
class MyClass(object):
= Класс в новом стилеclass MyClass:
= Класс нового стиля (неявно наследуется от object
)Python 2
class MyClass(object):
= Класс в новом стилеclass MyClass:
= СТАРЫЙ СТИЛЬ КЛАССАПри определении базовых классов в Python 3.x вы можете удалить object
из определения. Однако это может открыть дверь для серьезной проблемы, которую трудно отследить...
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()
для объекта старого стиля, вы просто получаете "instance". На объекте нового стиля вы получаете его класс.
Синтаксис инструкции создания класса:
class <ClassName>(superclass):
#code follows
В отсутствие каких-либо других суперклассов, которые вы специально хотите наследовать, superclass
всегда должен быть object
, который является корнем всех классов в Python.
object
является технически корнем классов "нового стиля" в Python. Но классы нового стиля сегодня так же хороши, как быть единственным стилем классов.
Но если вы не используете явное использование слова object
при создании классов, то, как упоминалось выше, Python 3.x неявно наследует от суперкласса object
. Но я думаю, что явный всегда лучше, чем неявный (ад)
Это создает класс нового стиля.