细说python类3——类的创建过程
来源:互联网 发布:易语言json解析模块 编辑:程序博客网 时间:2024/06/11 00:01
先来介绍一下python的__call__函数,call的作用是什么呢?举个例子来说明一下:
>>> class A(object):
... def __init__(self):
... print 'a'
... def __call__(self):
... print 'call'
...
>>> a=A()
a
>>> a()
call
据说a()这么使用的时候相当于执行a.__call__(),我们暂且这么理解,具体原因请参考专业文档,这里看可能a()没啥用,请继续向后看。
接下来,说一下类的type,
>>> class B:
... def __init__(self):
... print 'b'
...
>>> b=B()
b
>>> type(B)
<type 'classobj'>
>>> B
<class __main__.B at 0x7fdf94c086b0>
>>> type(b)
<type 'instance'>
>>> type(type(B))
<type 'type'>
>>> B
<class __main__.B at 0x7fdf94c086b0>
由上面例子可以看出类,实例的数据类型。
之后用type函数,创建一个类,type()函数,大致需要以下几个参数,第一个是类的name,第二个是这个类的父类,之后是属性。这里name指的是<class __main__.B at 0x7fdf94c086b0>这里面__main__后面跟的字符。为了保持一致,通常与类的名字一样。
>>> A=type('A',(object,),{'name':'aaa'})
>>> A
<class '__main__.A'>
可以看出我们的类A已经创建成功
>>> type(A)
<type 'type'>
但是为什么type(A)类型还是type,而不是<type 'classobj'>呢?因为type(A)和type(type('A',(object,),{'name':'aaa'}))是一样的,我猜classobj就是一个别名,但是我们用最原始的方法没显示别名,所以只显示type,但这不重要,重点是类已经创建了。那么我们自己封装一个类继承type去创建类呢?
>>> class MyType(type):
... def __init__(self,name,bases,dict):
... print 'mytype'
... def __call__(self,*args,**kwargs):
... print 'mytype call'
这里我们参数和type的源码一致,相当于重写了type的init和call,之后写一个B类,把B的__metaclass__指向myType,
>>> class B:
... __metaclass__=MyType
... def __init__(self):
... print 'b'
>>> b=B()
mytype call
>>> b
实例化一个b,可以看到,执行了MyType的init,但是b并没有生成任何东西。
这里解释一下,当执行b=B()时,需要先找到类内部的__metaclass__并执行,按照__metaclass__顺序先来执行__init__创建一个最初的类,类需要实例化,当我们实例化时会调用metaclass的__call__函数(这样使用B(),就解释了上面的call方法),__call__函数内部正常会调用B类里面的__new__方法来创建一个类的对象,之后会调用B里面的__init__函数给对象进行最初的包装(把相关的参数赋值等操作),最后返回这个类的对象,再把这个对象付赋给b,这样就完成了实例化的过程。因为MyType的__call__方法只打印了一串信息,所以这个实例没有值。也就是说正常创建一个实例对象的其实是new而不是init,init只是起到一个赋值的作用。下面代码模拟一下类的实例化过程:
def __call__(self,*args,**kwargs):
print 'mytype call'
re=self.__new__(self,*args,**kwargs)
self.__init__(re)
return re
class B:
__metaclass__=MyType
def __init__(self):
self.name='b'
print 'B'
def __new__(cls,*args,**kwargs):
return object.__new__(cls,*args,**kwargs)
def Func(self):
print 'Func'
def __call__(self):
print 'call'
b=B()
print b
print b.name
执行结果如下:
mytype
mytype call
B
<__main__.B object at 0x7fd84d7ae710>
b
- 细说python类3——类的创建过程
- python类创建过程
- 细说python类1——经典类和新式类
- 细说python类2——类动态添加方法和slots
- 细说 HttpHandler 的映射过程
- 细说 HttpHandler 的映射过程
- 细说 HttpHandler 的映射过程
- Python 客制化类的创建过程
- 细说继承Thread类和实现Runnable接口来创建线程的区别
- Python 类的创建
- 细说创建Hibernate程序的四大步骤
- c#—细说多线程(3)
- Java类对象的创建过程
- laravel创建工具类的过程
- Mozilla研究—组件的创建过程
- 静态类加载过程、对象的创建过程
- CView类创建过程
- 细说存储过程
- 【ZJOI2008】【BZOJ1034】泡泡堂BNB
- Linux Centos 6.6安装Mysql
- mysql压缩包如何使用及PoolableConnectionFactory 和Access denied for user 'testdb'@'localhost'问题的解决
- Android 自定义View (三) 圆环交替 等待效果
- 图像编辑之对比度调整(亮度对比度的算法公式)
- 细说python类3——类的创建过程
- 面向接口编程详解(三)
- Spring-tx声明式事务、@Transaction注解事务
- MT8382
- RecyclerView初步认识
- VMware建立一个裸机linux
- jsp国际化/格式化标签库
- Linux周期性自动发送邮件
- Cocos2d Android项目手动编译日记之SDK版本(一)