2017-02-22 7 views
6

Python имеет встроенную функцию type, и каждый экземпляр также имеет атрибут __class__. Я вообще считал, что они вернули то же самое. Даже документация и созвучно:Когда тип (экземпляр) не является экземпляром .__ class__?

instance.__class__

Класс, к которому принадлежит экземпляр класса.

и

type(object)

С одним аргументом, возвращает тип объекта.

Однако в abc.ABCMeta.__instancecheck__ есть проверка, если они идентичны (слегка укороченный):

subclass = instance.__class__ 
subtype = type(instance) 
if subtype is subclass: 

Когда не будет ли это так? Когда type(instance) не совпадает с instance.__class__?

+0

Возможный дубликат http://stackoverflow.com/questions/9610993/python-type-or-class-or-is – Kasramvd

+0

@Kasramvd Спасибо за эту ссылку, я считаю, что это скорее дубликат http: // stackoverflow. ком/вопросы/1060499/разница между ними-typeobj-и-OBJ-класса. Я не уверен, почему они не появлялись, когда решали вопрос, и ни в «предлагаемых дубликатах», когда задавали вопрос. – MSeifert

+0

Да, это случается иногда;) – Kasramvd

ответ

2

Это случай для объектов старого стиля (унаследованных от ничего). Такие объекты не имеют свойства __class__. Я думаю, что они делают это таким образом, чтобы предотвратить ошибки. Пример для Python 2.7:

class A: 
    pass 

class B(object): 
    pass 

a = A() 
b = B() 

print(dir(a)) # ['__doc__', '__module__'] 
print(dir(b)) # ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] 

print(b.__class__) # <class '__main__.B'> 
print(type(b))  # <class '__main__.B'> 

##################### 
# The intersting part 
print(a.__class__) # __main__.A 
print(type(a))  # <type 'instance'> 


print(B.__class__) # <type 'type'> 
print(type(B))  # <type 'type'> 

print(type(A))  # <type 'classobj'> 
#print(A.__class__) # AttributeError: class A has no attribute '__class__' 

Смотрите это для получения дополнительной информации:

Примечание: Приведенные строки из CPython были изменены в 2008 последний раз (commit), так что это действительно похоже на предмет совместимости или они просто забыли об этом.

+0

Хотя это имеет смысл - я думал о (забыл упомянуть об этом явно) о python 3.x и больше не существует классов старого стиля , – MSeifert

+0

@MSeifert Данные строки из cpython были изменены в 2008 году в последний раз (https://github.com/python/cpython/commit/68f5fbe94488b671ee6dfae74d918cc6a8eeca56), так что это похоже на совместимость или они просто забыли об этом. – ppasler

+0

@MSeifert Я обновил свой ответ. – ppasler

Смежные вопросы