В чем разница между "типом" и "объектом" в Python

Я натолкнулся на это чтение python документации по ключевому слову super:

Если второй аргумент опущен, возвращаемый суперобъект является несвязанным. Если вторым аргументом является объект, isinstance (obj, type) должен быть истинным. Если вторым аргументом является тип, issubclass (type2, type) должен быть истинным (это полезно для методов класса).

Может кто-нибудь, пожалуйста, дайте мне пример различия между передачей типа в качестве второго аргумента против передачи объекта?

Является ли документация о экземпляре объекта?

Спасибо.

Ответ 1

Python super функция делает разные вещи в зависимости от того, что это аргументы. Вот демонстрация различных способов его использования:

class Base(object):
    def __init__(self, val):
        self.val = val

    @classmethod
    def make_obj(cls, val):
        return cls(val+1)

class Derived(Base):
    def __init__(self, val):
        # In this super call, the second argument "self" is an object.
        # The result acts like an object of the Base class.
        super(Derived, self).__init__(val+2)

    @classmethod
    def make_obj(cls, val):
        # In this super call, the second argument "cls" is a type.
        # The result acts like the Base class itself.
        return super(Derived, cls).make_obj(val)

Тестовый вывод:

>>> b1 = Base(0)
>>> b1.val
0
>>> b2 = Base.make_obj(0)
>>> b2.val
1
>>> d1 = Derived(0)
>>> d1.val
2
>>> d2 = Derived.make_obj(0)
>>> d2.val
3

Результатом 3 является комбинация предыдущих модификаторов: 1 (из Base.make_obj) плюс 2 (из Derived.__init__).

Обратите внимание, что можно вызвать super только с одним аргументом, чтобы получить "несвязанный" суперобъект, он, по-видимому, бесполезен для многих. На самом деле нет никаких причин делать это, если вы не хотите возиться с внутренностями Python и не знаете, что делаете.

В Python 3 вы также можете вызывать super без аргументов (что эквивалентно вызовам в функциях выше, но более волшебно).

Ответ 2

Объектом может быть любой экземпляр класса Python, который может быть определен или не определен пользователем. Но, когда вы говорите о типе, он ссылается на объекты/коллекции по умолчанию, такие как list/tuple/dict/int/str и т.д.

Ответ 3

Вот простое исследование двух функций. Я обнаружил, что это освещает происходящее. Я часто создаю простую программу, исследующую все простые и простые функции и сохраняю их для справки:

#
# Testing isinstance and issubclass
#

class C1(object):
    def __init__(self):
        object.__init__(self)

class B1(object):
    def __init__(self):
        object.__init__(self)

class B2(B1):
    def __init__(self):
        B1.__init__(self)

class CB1(C1,B1):
    def __init__(self):
        # not sure about this for multiple inheritance
        C1.__init__(self)
        B1.__init__(self)

c1 = C1()
b1 = B1()
cb1 = CB1()

def checkInstanceType(c, t):
    if isinstance(c, t):
        print c, "is of type", t
    else:
        print c, "is NOT of type", t

def checkSubclassType(c, t):
    if issubclass(c, t):
        print c, "is a subclass of type", t
    else:
        print c, "is NOT a subclass of type", t

print "comparing isinstance and issubclass"
print ""

# checking isinstance
print "checking isinstance"

# can check instance against type
checkInstanceType(c1, C1)
checkInstanceType(c1, B1)
checkInstanceType(c1, object)

# can check type against type
checkInstanceType(C1, object)
checkInstanceType(B1, object)

# cannot check instance against instance
try:
    checkInstanceType(c1, b1)
except Exception, e:
    print "failed to check instance against instance", e

print ""

# checking issubclass
print "checking issubclass"

# cannot check instance against type
try:
    checkSubclassType(c1, C1)
except Exception, e:
    print "failed to check instance against type", e

# can check type against type
checkSubclassType(C1, C1)
checkSubclassType(B1, C1)
checkSubclassType(CB1, C1)
checkSubclassType(CB1, B1)

# cannot check type against instance
try:
    checkSubclassType(C1, c1)
except Exception, e:
    print "failed to check type against instance", e

Edit: Также рассмотрим следующее, поскольку isststance может нарушить реализации API. Примером может служить объект, который действует как словарь, но не является производным от dict. isinstance может проверить, что объект является словарем, даже если объект поддерживает доступ к стилю словаря: isinstance считается вредным

Edit2:

Может кто-нибудь, пожалуйста, дайте мне пример различия между передачей типа в качестве второго аргумента против передачи объекта?

После тестирования вышеуказанного кода он говорит мне, что вторым параметром должен быть тип. Итак, в следующем случае:

checkInstanceType(c1, b1)

Сбой вызова. Его можно было бы написать:

checkInstanceType(c1, type(b1))

Итак, если вы хотите проверить тип одного экземпляра напротив другого экземпляра, вы должны использовать встроенный вызов type().