python类和对象的底层实现
2024-08-28 12:56:44
按照python中"一切皆对象的原理",所有创建的对象,都是一个已知存在的class实例化的结果;那么class又是被哪个"类"实例化的呢?先看下面的一段代码
class Foo(object):
pass obj = Foo()
print type(obj)
print type(Foo) 结果为:
<class '__main__.Foo'>
<type 'type'>
可以看到:obj是由Foo实例化,而Foo由type类创建
这样Foo就可以这样实现了,看下面:
def func(self):
print "charles" Foo = type('Foo',(object,),{'func':func})
print Foo
f = Foo()
f.func() 结果为:
<class '__main__.Foo'>
charles
那么问题随之产生了,既然class是由type实例化而来的,那么type中是如何实现类的创建的呢?
实际上,在被type实例化的类中,有一个__metaclass__字段,指明由谁来实例化得到该类
class MyType(type): def __init__(self, what, bases=None, dict=None):
print "333"
super(MyType, self).__init__(what, bases, dict) def __call__(self, *args, **kwargs):
print "444"
obj = self.__new__(self, *args, **kwargs) self.__init__(obj) class Foo(object): __metaclass__ = MyType def __init__(self):
print '222' def __new__(cls, *args, **kwargs):
print '1111'
return object.__new__(cls, *args, **kwargs) obj = Foo() 结果为:
333
444
1111
222
可以看到Mytype和Foo都存在__new__()方法,那么这个方法是干什么的呢?
__new__()函数:
看下面:
class A(object):
def __init__(self):
print 'init' def __new__(cls, *args, **kwargs):
print "first"
print object.__new__(cls,*args,**kwargs)
A() 结果:
first
<__main__.A object at 0x0000000002730EB8>
可以看到__new__方法比__init__方法先执行,object.__new__(cls,*args,**kwargs)为A的实例化的对象,如果我打印self的话
class A(object):
def __init__(self):
print self,'----'
print 'init' def __new__(cls, *args, **kwargs):
print "first"
print object.__new__(cls,*args,**kwargs)
return object.__new__(cls,*args,**kwargs)
A() 结果为:
first
<__main__.A object at 0x000000000260BE10>
<__main__.A object at 0x000000000260BE10> ----
init
可以看到self的值,正好是__new__返回的结果;
观察__new__返回的对象,参数中包含cls,表示当前的类,如果传入的不是当前的类(即使是父类),__init__不会被调用:
class B(object):
pass
class A(B):
def __init__(self):
print self,'----'
print 'init' def __new__(cls, *args, **kwargs):
print "first"
return object.__new__(B,*args,**kwargs)
A() 结果为:
first
<__main__.A object at 0x000000000238BEB8>
结论:1、python的类的实例,是__new__方法创建的
2、__new__方法必须有一个cls参数,表示当前类,只有传入的是当前cls,__init__才会被调用
3、类的实例self,就是__new__方法return object.__new__(cls,*args,**kwargs)的结果;
参考:http://www.cnblogs.com/tuzkee/p/3540293.html
http://www.cnblogs.com/wupeiqi/p/4766801.html
最新文章
- Thinking in Unity3D
- 【移动端兼容问题研究】javascript事件机制详解(涉及移动兼容)
- java的finalize()函数
- Loadrunne实现多个场景运行
- 解决Windows Server2008 R2中IE开网页时弹出阻止框(Windows Server2008网页无法打开的问题)
- C语言enum再学习
- RMAN备份之丢失数据文件及控制文件的恢复
- MySQL优化GROUP BY-松散索引扫描与紧凑索引扫描
- ntity Framework技巧系列之四 - Tip 13 – 15
- registration_db.go
- [原创]GDB调试指南-断点设置
- redis应用--位图
- python程序如何脱离ide而在操作系统上执行
- docker容器启动设置固定IP
- Hibernate注解开发、注解创建索引
- DNS 基础
- 浏览器多进程架构、浏览器内核多线程、js单线程、GUI 渲染线程 与 JavaScript引擎线程互斥 原理
- Daily Scrum NO.8
- LeetCode134:Gas Station
- 使用WebClient與HttpWebRequest的差異