2012-03-14 1 views
15

Как можно получить экземпляр класса, который является object, без класса, являющегося подклассом object? вот пример:Экземпляры - это «объект», но класс не является подклассом «объекта»: как это возможно?

>>> class OldStyle(): pass 
>>> issubclass(OldStyle, object) 
False 
>>> old_style = OldStyle() 
>>> isinstance(old_style, object) 
True 

ответ

18

В Python 2, типа и класса не то же самое, в частности, для классов старого стиля, type(obj)is not the same object как obj.__class__. Таким образом, это возможно потому, что экземпляры классов старого стиля на самом деле другого типа (instance), чем их класс:

>>> class A(): pass 
>>> class B(A): pass 
>>> b = B() 

>>> assert b.__class__ is B 
>>> issubclass(b.__class__, A) # same as issubclass(B, A) 
True 
>>> issubclass(type(b), A) 
False 

>>> type(b) 
<type 'instance'> 
>>> b.__class__ 
<class __main__.B at 0x10043aa10> 

Это решается в новых классов:

>>> class NA(object): pass 
>>> class NB(NA): pass 
>>> nb = NB() 
>>> issubclass(type(nb), NA) 
True 
>>> type(nb) 
<class '__main__.NB'> 
>>> nb.__class__ 
<class '__main__.NB'> 

Старый стиле класс не является типом, класс нового типа:

>>> isinstance(A, type) 
False 
>>> isinstance(NA, type) 
True 

Классы старого стиля объявлены устаревшими. В Python 3 есть только классы нового стиля; class A() эквивалентен class A(object), и ваш код даст True в обеих проверках.

Взгляните на этот вопрос для более некоторого обсуждения: What is the difference between old style and new style classes in Python?

+0

+1: Это очень четкое описание и очень хороший момент. Благодаря! – EOL

+0

Для тех, кто задается вопросом, 'isinstance' является [специальным обложением] (https://github.com/python/cpython/blob/e6a0b5982973e64b9fa28e5e3e54eb8c47882780/Objects/abstract.c#L2898) для экземпляров и классов старого стиля (т.е.' PyClass_Check (cls) && PyInstance_Check (inst) 'в C). Поскольку нет отношения типа к типу, он получает экземпляр '__class__' экземпляра для проверки' issubclass', который также [с особым обложением] (https://github.com/python/cpython/blob/e6a0b5982973e64b9fa28e5e3e54eb8c47882780/Objects /classobject.c#L486) для классов старого стиля. – eryksun

6

Все это объект:

isinstance(123, object) # True 
isinstance("green cheese", object) # True 
isinstance(someOldClassObject, object) # True 
isinstance(someNewClassObject, object) # True 
isinstance(object, object) # True 
isinstance(None, object) # True 

Обратите внимание, что этот вопрос не имеет по существу ничего общего с староголландскими против новых классов. isinstance(old_style, object), являющийся True, является просто следствием того, что каждое значение в python является экземпляром object.

+0

У вас есть ссылка на это? – EOL

+1

@EOL: [этот] (http://www.cafepy.com/article/python_types_and_objects/python_types_and_objects.html) весьма полезен – georg

+1

Спасибо. Я взглянул на ссылку, но я не могу найти нигде никаких указаний на мысль о том, что все в Python имеет * тип * 'object' (тот факт, что« все является объектом »в Python, не означает одно и то же). – EOL

1

Когда вы делаете Выражение

old_style = OldStyle() 

Это означает, что вы инстанцирование объекта, который old_style является экземпляром класса Oldstyle.

Также оценивается значение True в Python 3.2.