class Foo:
pass
foo = Foo()
print type(Foo), foo.__class__, Foo.__bases__, isinstance(foo, type)
class Bar(object):
pass
bar = Bar()
print type(Bar), bar.__class__, Bar.__bases__, isinstance(bar, type)
返回結果為
<type 'classobj'> __main__.Foo () False
<type 'type'> <class '__main__.Bar'> (<type 'object'>,) False
上面的代碼中Foo為古典類型,而Bar為新式類。新式類要求繼承自object或者內建類型。事實上,內置類型也都繼承自object
print int.__bases__ #(<type 'object'>,)
print type.__bases__ #(<type 'object'>,)
元類
古典類的元類為types.ClassType, 而新式類的元類為type
print bar.__class__.__class__ #<type 'type'>
__init__()不是構造方法
class Foo(object):
def __new__(cls, *args, **kwargs):
print cls
print args
print kwargs
instance = object.__new__(cls, *args, **kwargs)
print instance
def __init__(self, a, b):
print "init gets called"
print "self is", self
self.a, self.b = a,b
foo = Foo(1,2)
我們注意到,__init__()方法并沒有被調用。
事實上__new__()方法才是真正的構造函數。而且__new__()是類方法,一般會返回對象實例。而__init__()是實例方法,只有當__new__()方法返回實例對象之后才會被調用,對這個實例對象進行初始化工作。
一般情況下,我們不需要覆蓋__new__()方法,但是當子類繼承自不可變類型時,往往要覆蓋這個方法。