Python中的“类型”和“对象”之间有什么区别

时间:2013-03-30 06:15:32

标签: python object types

我在super关键字

上阅读了python documentation

如果省略第二个参数,则返回的超级对象是未绑定的。如果第二个参数是对象,则isinstance(obj,type)必须为true。如果第二个参数是一个类型,则issubclass(type2,type)必须为true(这对于classmethods很有用)。

有人可以举个例子来说明将一个Type作为第二个参数传递给传递一个Object吗?

文档是否在讨论对象的实例?

谢谢。

3 个答案:

答案 0 :(得分:5)

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(相当于提供当前类和self作为两个参数,但更神奇)。

答案 1 :(得分:0)

对象可以是任何Python类实例,可以是也可以不是用户定义的。但, 当你谈论类型时,引用默认对象/集合,如list / tuple / dict / int / str等。

答案 2 :(得分:0)

这是对这两个功能的简单探索。我发现这个练习很有启发性。我经常会创建一个简单的程序来探索简单函数的细节并保存以供参考:

#
# 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

修改 还要考虑以下因为isinstance可以破坏API实现。一个例子是一个像字典一样的对象,但不是从dict派生的。 isinstance可能会检查对象是否为字典,即使该对象支持字典样式访问: isinstance considered harmful

<强> EDIT2:

  

有人可以举个例子来说明将一个Type作为第二个参数传递给传递一个Object吗?

测试上面的代码后,它告诉我第二个参数必须是一个类型。所以在以下情况中:

checkInstanceType(c1, b1)

通话失败。它可以写成:

checkInstanceType(c1, type(b1))

因此,如果要针对另一个实例检查一个实例的类型,则必须使用type()内置调用。