Python中一切皆对象:字符是对象,列表是对象,内建类型(built-in type)也是对象;
用户定义的类型是对象,object
是对象,type
也是对象。
自Python2.2之后,为了弥补内建类型和古典类(classic classes)之间的鸿沟引入了新式类(new-style classes)。
在新式类中,object是所有内建类型的基类,用户所定义的类可以继承自object也可继承自内建类型。
内建类型、 object
、type
以及用户所定义的类之间关系
内建类型、 object
、type
以及用户所定义的类之间到底有什么关系呢?
它们之间本质上有什么不同吗?看一个简单的例子:
class A:
pass
class B(object):
pass
class C(type):
pass
class D(diet):
pass
现在有类A、B、C、D的实例分别对应为a、b、c、d,看一组求值的结果,如表6-1所示。
从表6-1中可以得出如下结论:
object[l]
和古典类[3]没有基类,type[2]
的基类为object
。- 新式类([4],[5],[6])中
type()
的值和__class__
的值是一样的, 但古典类[3]中实例的type
为instance
,其type()
的值和__class__
的值不一样。 - 继承自内建类型的用户类的实例[6]也是
object
的实例,object[l]
是type
的实例,type
实际是个元类(metaclass)。 - object和内建类型以及所有基于type构建的用户类[5]都是
type
的实例。 - 在古典类中,所有用户定义的类的类型都为
instance
。
综上,不同类型的对象之间的关系如图6-1所示。
class TestNewClass:
__metaclass__ = type
type (TestNewClass)
type
TestNewClass.__bases__
(object,)
a= TestNewClass ()
type (a)
__main__.TestNewClass
a.__class__
__main__.TestNewClass
从上述例子可以看出,TestNewClass
在定义的时候并没有继承任何类,
但测试的结果表明其父类为 object
,它还是属于新式类。
这其中的原因在于 TestNewClass
中设置了__metaClass__
属性。
所以并不能简单地从定义的形式上来判断一个类是新式类还是古典类,而应当通过元类的类型来确定类的类型:
古典类的元类为 types.ClassType
,新式类的元类为 type
类。
新式类相对于古典类来说有很多优势:能够基于内建类型构建新的用户类型,
支持 property
和描述符特性等。作为新式类的祖先, Object
类中还定义了一些特殊方法,
如:__new__()
, __init__()
,__delattr__()
,__getattribute__()
,
__setattr__()
, __hash__()
, __repr__()
,__str__()
等。
object
的子类可以对这些方法进行覆盖以满足自身的特殊需求。
注:在Python中一切皆对象,type
也是对象。