Есть ли какая-либо причина для объявления класса наследовать 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 вставляет его для вас. за кулисами.
object
. IIRC был момент, когда еще не все встроенные типы были перенесены в классы нового стиля.
object
. У меня есть Python 2.2.3, и после быстрой проверки я не смог найти нарушителя, но позже я перефразирую ответ, чтобы сделать его более понятным. Было бы интересно, если бы вы могли найти пример, мое любопытство задето.
object
.
staticmethod
и classmethod
отлично работает даже на уроках старого стиля. property
Сорта работает для чтения в классах старого стиля, просто не перехватывает записи (поэтому, если вы присваиваете имя, экземпляр получает атрибут с заданным именем, который скрывает свойство). Также обратите внимание, что __slots__
улучшение скорости доступа к атрибутам в основном сводится к устранению потерь, связанных с доступом к атрибутам классов нового стиля, поэтому это не совсем выгодно для классов нового стиля (хотя экономия памяти - это точка продажи).
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 слезы.
__metaclass__ = type
в верхнюю часть модуля (после from __future__ import absolute_import, division, print_function
строки :-)); это хак совместимости в Py2, который делает все впоследствии определенные классы в модуле новым стилем по умолчанию, а в Py3 он полностью игнорируется (просто случайная глобальная переменная сидит без дела), поэтому он безвреден.
Да, это объект «нового стиля». Это была функция, представленная в python2.2.
Новые объекты типа имеют различную объектную модель для классических объектов, и некоторые вещи не будут работать должным образом со старыми объектами типа, например, super()
, @property
и дескрипторы. См. Эту статью для хорошего описания того, что новый класс стиля.
Так что ссылка для описания различий: В чем разница между старым стилем и новым стилем классов в Python?
object
Python 2.
История от изучения Python трудный путь :
Оригинальное представление Python класса было сломано во многих серьезных отношениях. К тому времени, когда эта ошибка была признана, было уже слишком поздно, и они должны были поддержать это. Чтобы решить проблему, им нужен был стиль «новый класс», чтобы «старые классы» продолжали работать, но вы можете использовать новую, более правильную версию.
Они решили, что будут использовать слово «объект» в нижнем регистре как «класс», от которого вы наследуете, чтобы создать класс. Это сбивает с толку, но класс наследует от класса с именем «объект», чтобы создать класс, но на самом деле это не объект, а класс, но не забывайте наследовать от объекта.
Также просто для того, чтобы вы знали, в чем разница между классами нового стиля и классами старого стиля, это то, что классы нового стиля всегда наследуются от object
класса или от другого класса, унаследованного от object
:
class NewStyle(object):
pass
Другой пример:
class AnotherExampleOfNewStyle(NewStyle):
pass
В то время как базовый класс старого стиля выглядит так:
class OldStyle():
pass
И дочерний класс старого стиля выглядит так:
class OldStyleSubclass(OldStyle):
pass
Вы можете видеть, что базовый класс старого стиля не наследуется ни от какого другого класса, однако классы старого стиля могут, конечно, наследовать друг от друга. Наследование от объекта гарантирует, что определенная функциональность доступна в каждом классе Python. Новые классы стиля были введены в Python 2.2
object
не так уж и запутан, и на самом деле он довольно стандартный. Smalltalk имеет корневой класс с именем Object
и корневой метакласс Class
. Почему? Потому что, так же как Dog
и класс для собак, Object
это класс для объектов и Class
класс для классов. Java, C #, ObjC, Ruby и большинство других основанных на классах ОО-языков, которые люди используют сегодня и которые имеют корневой класс, используют в Object
качестве имени некоторые вариации, а не только Python.
Да, это исторически . Без этого он создает класс в старом стиле.
Если вы используете type()
объект старого стиля, вы просто получаете «экземпляр». На объекте нового стиля вы получаете его класс.
type()
класс старого стиля, вы получите «classobj» вместо «type».
Синтаксис оператора создания класса:
class <ClassName>(superclass):
#code follows
В отсутствие каких-либо других суперклассов, от которых вы конкретно хотите наследовать, superclass
всегда должно быть object
, что является корнем всех классов в Python.
object
технически является корнем классов "нового стиля" в Python. Но классы нового стиля сегодня так же хороши, как и единственный стиль занятий.
Но если вы не используете слово явно object
при создании классов, то, как уже упоминалось, Python 3.x неявно наследуется от object
суперкласса. Но я думаю, что явное всегда лучше, чем неявное (ад)