文章目录
Python中一切事物都是对象
metaclass,类的祖宗
如引言中所述,既然一切事物都是对象,所以类也是一个“对象”
问题:类这个“对象”是怎么生成的?
类这个对象其实是 “type” 这个父类创建的,可以查看一下type这个类
查看type类
class type(object):
"""
type(object_or_name, bases, dict)
type(object) -> the object's type
type(name, bases, dict) -> a new type
"""
*******************省略****************************省略*********************************
__itemsize__ = 40
__mro__ = (
None, # (!) forward: type, real value is "<class 'type'>"
object,
)
__name__ = 'type'
__qualname__ = 'type'
__text_signature__ = None
__weakrefoffset__ = 368
可以看到type类也是继承了object类的,那再接着看看object类
class object:
"""
The base class of the class hierarchy.
When called, it accepts no arguments and returns a new featureless
instance that has no instance attributes and cannot be given any.
"""
object类是一个最顶层的基类,
小结
所以,平常我们创建的对象是写的类的实例,而写的类其实是type的对象。所以创建类有两种方式:
普通方式创建类
class Foo:
def func(self):
pass
特殊方式(通过type类的构造函数创建类)
def func(self):
pass
foo = type("Foo",(object,),{"func":func})
# type 第一个参数:类名
# type 第二个参数:当前类的基类
# type 第三个参数:类的成员
type 第一个参数:类名
type 第二个参数:当前类的基类
type 第三个参数:类的成员
问题一:type类中如何实现创建类?
类中有一个属于 “metaclass()” 用来表示该类由谁来实例化创建,所以,我们可以为__metaclass__ 设置一个type类的派生类,从而查看 类创建的过程
def function(self):
print("function test")
foo = type("Foo",(object,),{"func":function})
# type 第一个参数:类名
# type 第二个参数:当前类的基类
# type 第三个参数:类的成员
foo 是类名,object是继承的这个类,func是成员类型,
object是一个超级的类,所有的类都会继承这个object的类,你不写他也继承。
自定义祖宗类
class MyType(type):
def __init__(self,*args,**kwargs):
print("123")
pass
def __call__(self, *args, **kwargs):
print("456")
class Foo(object,metaclass=MyType):
def func(self):
print("Hello World")
obj = Foo()
"""
123
456
"""
如上,在继承时通过 metaclass= … 来定义这个类创建时的祖宗类来自于哪里。缺省情况下,创建类的时候会通过type这个类来创建,这里使用metaclass 指定通过哪个类来创建。
输出结果解析:
456:python一切皆对象,所以Foo其实是相当于是Mytype的对象(或者叫实例),再执行“Foo()”就会自动执行类里面的"call"方法,所以输出了“456”
123:123是类里面"init()“方法的内容,所以在通过类创建对象的时候会自动执行类里面的”“init()”" 所以进行了输出。
示例结论
本例主要是说明了可以通过metaclass 来指定祖宗类,如上示例所示,MyType就是手动创建的基类。
问题二:类又是如何创建对象?
注意上面所说的,通过类创建一个对象,然后“对象()” 会执行类的call方法。但是对象具体是怎么创建出来的呢?其实前面说过很多特殊方法,但是还有一个特殊方法是“new()”专用于通过类创建对象时自动执行的方法
简单的示例
class MyType(type):
def __init__(self,*args,**kwargs):
print("123")
pass
def __call__(self, *args, **kwargs):
return self.__new__()
class Foo(object,metaclass=MyType):
def __init__(self):
pass
@classmethod
def __new__(cls, *args, **kwargs):
return "object"
obj = Foo()
print(obj)
"""
123
object
"""
剖析代码运行流程
- 第一步:代码从上至下运行到“class Foo(object,metaclass=MyType):”时,会自动执行“class MyType(type):”中的“init(self,*args,**kwargs)”方法,所以会打印一下“123”
- 第二步:代码运行至 “obj = Foo()”时,因为“Foo”已经是个对象了,所以Foo() 会执行“MyType”中的__call__方法
- 第三步:__call__方法,又返回"self.new()"方法,所以又转到“class Foo(object,metaclass=MyType):”中,返回object对象后,将返回值返回给obj对象。
class MyType(type):
def __init__(self,what,bases=None,dict=None):
super(MyType,self).__init__(what,bases,dict)
def __call__(self, *args, **kwargs):
obj = self.__new__(self,*args,**kwargs)
self.__init__(obj)
class Foo(object,metaclass=MyType):
def __init__(self,name):
self.name = name
@classmethod
def __new__(cls, *args, **kwargs):
return object.__new__(cls,*args,**kwargs)
obj = Foo()