Ответ на этот вопрос (хотя и простой) найти довольно сложно. Поиск в Google, например, «базовый класс объектов Python» или аналогичные, приводит к появлению страниц и страниц учебных пособий по объектно-ориентированному программированию. Апвоттинг, потому что это первая ссылка, которая привела меня к поисковым терминам "старые и новые объекты Python"
суперспирант
Ответы:
765
Есть ли какая-либо причина для объявления класса наследовать object?
В Python 3, кроме совместимости между Python 2 и 3, нет причин . В Python 2 много причин .
История Python 2.x:
В Python 2.x (начиная с 2.2) есть два стиля классов в зависимости от наличия или отсутствия objectв качестве базового класса:
классические классы стиля : они не имеют objectбазового класса:
>>>classClassicSpam:# no base class...pass>>>ClassicSpam.__bases__
()
«новые» классы стилей : они имеют, прямо или косвенно (например, наследуют от встроенного типа ), objectв качестве базового класса:
>>>classNewSpam(object):# directly inherit from object...pass>>>NewSpam.__bases__
(<type 'object'>,)>>>classIntSpam(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: Создание функций для управления получением, установкой и удалением атрибута.
Если вы не наследуете object, забудьте об этом. Более полное описание предыдущих пунктов маркировки наряду с другими преимуществами «новых» классов стилей можно найти здесь .
Одним из недостатков классов нового стиля является то, что сам класс требует больше памяти. Если, конечно, вы не создаете много объектов класса, я сомневаюсь, что это будет проблемой, и это будет негативное погружение в море позитива.
История Python 3.x:
В Python 3 все упрощено. Существуют только классы нового стиля (именуемые просто классами), поэтому единственное отличие в добавлении objectсостоит в том, что требуется ввести еще 8 символов. Эта:
classClassicSpam:pass
полностью эквивалентно (кроме их имени :-) этому:
classNewSpam(object):pass
и к этому:
classSpam():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 был момент, когда еще не все встроенные типы были перенесены в классы нового стиля.
Бруно Desthuilliers
@brunodesthuilliers У меня сложилось впечатление, что все встроенные типы наследуются от object. У меня есть Python 2.2.3, и после быстрой проверки я не смог найти нарушителя, но позже я перефразирую ответ, чтобы сделать его более понятным. Было бы интересно, если бы вы могли найти пример, мое любопытство задето.
Димитрис Фасаракис Хиллиард
Честно говоря (см. «IIRC» в моем предыдущем комментарии), я не уверен на 101% в этом вопросе (все ли встроенные типы были уже преобразованы в классы нового стиля, когда были введены классы нового стиля) - я мог бы просто быть простым неправильно, или это могло касаться только некоторых стандартных типов lib (но не встроенных). Но все же я думаю, что было бы лучше уточнить, что в основе лежит класс нового стиля object.
Bruno Desthuilliers
7
слишком плохой стекопоток делает только upvote = upvote + 1 для таких любопытных ответов, хотелось бы, чтобы upvote + = N
PirateApp
1
staticmethodи classmethodотлично работает даже на уроках старого стиля. propertyСорта работает для чтения в классах старого стиля, просто не перехватывает записи (поэтому, если вы присваиваете имя, экземпляр получает атрибут с заданным именем, который скрывает свойство). Также обратите внимание, что __slots__улучшение скорости доступа к атрибутам в основном сводится к устранению потерь, связанных с доступом к атрибутам классов нового стиля, поэтому это не совсем выгодно для классов нового стиля (хотя экономия памяти - это точка продажи).
ShadowRanger
540
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 слезы.
«При определении базовых классов в Python 3.x вы можете исключить объект из определения. Однако это может открыть дверь для серьезной проблемы, которую трудно отследить…» К каким проблемам вы относитесь?
Эйдис
6
@Aidis: Я думаю, они имеют в виду, что код, который работает как на Py2, так и на Py3, подойдет для Py3, но будет разбит на Py2, если он опирается на функции класса нового стиля. Лично, если я пишу такой код, я пропускаю явное наследование и просто помещаю его __metaclass__ = typeв верхнюю часть модуля (после from __future__ import absolute_import, division, print_functionстроки :-)); это хак совместимости в Py2, который делает все впоследствии определенные классы в модуле новым стилем по умолчанию, а в Py3 он полностью игнорируется (просто случайная глобальная переменная сидит без дела), поэтому он безвреден.
ShadowRanger
400
Да, это объект «нового стиля». Это была функция, представленная в python2.2.
Новые объекты типа имеют различную объектную модель для классических объектов, и некоторые вещи не будут работать должным образом со старыми объектами типа, например, super(), @propertyи дескрипторы. См. Эту статью для хорошего описания того, что новый класс стиля.
+1 это. Обратите внимание, что классы старого стиля исчезли в Python 3, поэтому вам нужно наследовать только от objectPython 2.
9
Это не настоящий ответ. Я просто даю ссылку на другие статьи. Я думаю, что ответ Ярина должен быть принят как ответ на этот вопрос.
alwbtc
2
@alwbtc: В этом ответе тоже есть что-то новое. Например, упоминание о «super ()» привело меня к другому важному [здесь] ( stackoverflow.com/questions/576169/… ).
Оригинальное представление Python класса было сломано во многих серьезных отношениях. К тому времени, когда эта ошибка была признана, было уже слишком поздно, и они должны были поддержать это. Чтобы решить проблему, им нужен был стиль «новый класс», чтобы «старые классы» продолжали работать, но вы можете использовать новую, более правильную версию.
Они решили, что будут использовать слово «объект» в нижнем регистре как «класс», от которого вы наследуете, чтобы создать класс. Это сбивает с толку, но класс наследует от класса с именем «объект», чтобы создать класс, но на самом деле это не объект, а класс, но не забывайте наследовать от объекта.
Также просто для того, чтобы вы знали, в чем разница между классами нового стиля и классами старого стиля, это то, что классы нового стиля всегда наследуются от objectкласса или от другого класса, унаследованного от object:
classNewStyle(object):pass
Другой пример:
classAnotherExampleOfNewStyle(NewStyle):pass
В то время как базовый класс старого стиля выглядит так:
classOldStyle():pass
И дочерний класс старого стиля выглядит так:
classOldStyleSubclass(OldStyle):pass
Вы можете видеть, что базовый класс старого стиля не наследуется ни от какого другого класса, однако классы старого стиля могут, конечно, наследовать друг от друга. Наследование от объекта гарантирует, что определенная функциональность доступна в каждом классе Python. Новые классы стиля были введены в Python 2.2
Вызов корневого класса objectне так уж и запутан, и на самом деле он довольно стандартный. Smalltalk имеет корневой класс с именем Objectи корневой метакласс Class. Почему? Потому что, так же как Dogи класс для собак, Objectэто класс для объектов и Classкласс для классов. Java, C #, ObjC, Ruby и большинство других основанных на классах ОО-языков, которые люди используют сегодня и которые имеют корневой класс, используют в Objectкачестве имени некоторые вариации, а не только Python.
abarnert
30
Да, это исторически . Без этого он создает класс в старом стиле.
Если вы используете type()объект старого стиля, вы просто получаете «экземпляр». На объекте нового стиля вы получаете его класс.
Кроме того, если вы используете type()класс старого стиля, вы получите «classobj» вместо «type».
Джоэл Шегрен
7
Синтаксис оператора создания класса:
class<ClassName>(superclass):#code follows
В отсутствие каких-либо других суперклассов, от которых вы конкретно хотите наследовать, superclassвсегда должно быть object, что является корнем всех классов в Python.
objectтехнически является корнем классов "нового стиля" в Python. Но классы нового стиля сегодня так же хороши, как и единственный стиль занятий.
Но если вы не используете слово явно objectпри создании классов, то, как уже упоминалось, Python 3.x неявно наследуется от objectсуперкласса. Но я думаю, что явное всегда лучше, чем неявное (ад)
Ответы:
В Python 3, кроме совместимости между Python 2 и 3, нет причин . В Python 2 много причин .
История Python 2.x:
В Python 2.x (начиная с 2.2) есть два стиля классов в зависимости от наличия или отсутствия
object
в качестве базового класса:классические классы стиля : они не имеют
object
базового класса:«новые» классы стилей : они имеют, прямо или косвенно (например, наследуют от встроенного типа ),
object
в качестве базового класса:Без сомнения, при написании класса вы всегда захотите перейти на классы нового стиля. Льготы для этого многочисленны, чтобы перечислить некоторые из них:
Поддержка дескрипторов . В частности, следующие дескрипторы стали возможными с помощью дескрипторов:
classmethod
: Метод, который получает класс в качестве неявного аргумента вместо экземпляра.staticmethod
: Метод, который не получает неявный аргументself
в качестве первого аргумента.property
: Создание функций для управления получением, установкой и удалением атрибута.__slots__
Сохраняет потребление памяти классом, а также ускоряет доступ к атрибутам. Конечно, это накладывает ограничения .__new__
Статический метод: позволяет настроить как новые создаются экземпляры класса.Порядок разрешения методов (MRO) : в каком порядке будут искать базовые классы класса при попытке определить, какой метод вызывать.
Связанные с MRO,
super
звонки . Также смотрите,super()
считается супер.Если вы не наследуете
object
, забудьте об этом. Более полное описание предыдущих пунктов маркировки наряду с другими преимуществами «новых» классов стилей можно найти здесь .Одним из недостатков классов нового стиля является то, что сам класс требует больше памяти. Если, конечно, вы не создаете много объектов класса, я сомневаюсь, что это будет проблемой, и это будет негативное погружение в море позитива.
История Python 3.x:
В Python 3 все упрощено. Существуют только классы нового стиля (именуемые просто классами), поэтому единственное отличие в добавлении
object
состоит в том, что требуется ввести еще 8 символов. Эта:полностью эквивалентно (кроме их имени :-) этому:
и к этому:
Все имеют
object
по своему__bases__
.Итак, что нужно сделать?
В 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 трудный путь :
Также просто для того, чтобы вы знали, в чем разница между классами нового стиля и классами старого стиля, это то, что классы нового стиля всегда наследуются от
object
класса или от другого класса, унаследованного отobject
:Другой пример:
В то время как базовый класс старого стиля выглядит так:
И дочерний класс старого стиля выглядит так:
Вы можете видеть, что базовый класс старого стиля не наследуется ни от какого другого класса, однако классы старого стиля могут, конечно, наследовать друг от друга. Наследование от объекта гарантирует, что определенная функциональность доступна в каждом классе Python. Новые классы стиля были введены в Python 2.2
источник
object
не так уж и запутан, и на самом деле он довольно стандартный. Smalltalk имеет корневой класс с именемObject
и корневой метаклассClass
. Почему? Потому что, так же какDog
и класс для собак,Object
это класс для объектов иClass
класс для классов. Java, C #, ObjC, Ruby и большинство других основанных на классах ОО-языков, которые люди используют сегодня и которые имеют корневой класс, используют вObject
качестве имени некоторые вариации, а не только Python.Да, это исторически . Без этого он создает класс в старом стиле.
Если вы используете
type()
объект старого стиля, вы просто получаете «экземпляр». На объекте нового стиля вы получаете его класс.источник
type()
класс старого стиля, вы получите «classobj» вместо «type».Синтаксис оператора создания класса:
В отсутствие каких-либо других суперклассов, от которых вы конкретно хотите наследовать,
superclass
всегда должно бытьobject
, что является корнем всех классов в Python.object
технически является корнем классов "нового стиля" в Python. Но классы нового стиля сегодня так же хороши, как и единственный стиль занятий.Но если вы не используете слово явно
object
при создании классов, то, как уже упоминалось, Python 3.x неявно наследуется отobject
суперкласса. Но я думаю, что явное всегда лучше, чем неявное (ад)Ссылка
источник