Python __new__, __init__, __metaclass__, __call__, __del__, __getattr__, __getattribute__
2014-02-18 22:46
459 查看
1.__new__
![](http://img.blog.csdn.net/20140218215129562?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc2VjcmV0eA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
先得明白一个道理:类,本身也是对象,类对象。这个同java,不难理解。实在不好想,就认为类对象存储在一个特殊地方,用虚拟机能理解的方式描述着类的定义。
这段文档,重点是:__new__用来创建类对象,实例化一个cls的类对象,表示这个类已经被加载了,解析了,现在可以拿着这个类创建普通实例对象了。如果类对象创建失败,则不会调用init方法,这个符合常理,类都没有,哪来的对象。其用处是:自定义方式创建类对象,比如改变这个类的属性等。类对象,类的对象是两个概念:见下例
class A(object):
x = 0
def __init__(self, xx=None):
if xx:
self.xx == xx
a = A(5)
print a.xx # a是A类的对象,A类的一个实例
print A.x # A是A类的类对象,描述了A类的类结构信息
那么__new__方法就是用来创建 A.x 一句中的A(A类的类对象),换句话说,是虚拟机用来加载类的。大部分情况下,你看不到它,你也不会直接或者间接调用它。
2.__init__
![](http://img.blog.csdn.net/20140218220443718?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc2VjcmV0eA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
__init__学过OOP的都知道,构造函数。这个就是我们平常 a = A()一句会间接调用的函数。所以它应当在__new__之后被调用,要等__new__创建完类,才能根据类创建对象。
3.__del__
![](http://img.blog.csdn.net/20140218224949859?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc2VjcmV0eA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
当对象将要被销毁时,__del__被调用。这个is about to(将要),虚拟机无法保证是什么具体时间点。需要注意一点:del x 并不是立即调用x.__del__(),仅仅是把x的引用计数器减少1。当某个对象的引用计数器为0时,表示对象不再被引用,也就是无法被访问到,也就是可以被垃圾回收了。
同java虚拟机一样,Python垃圾回收也是如此:当一个对象引用计数器为0,也不代表着立即被回收,而是等到下一次垃圾回收时,才会被回收。即使引用计数器为0,并且立即显示调用gc.collect()进行垃圾回收,也不是立即被回收,因为gc.collect()一句[ java中对应System.gc() ]执行,并不代表立即垃圾回收,而是说“垃圾回收已经排上日程了,将在接下来的一段时间内调用,具体接下来多久,虚拟机无法保证一个明确的数”。关于Java的System.gc(),这个描述比较恰当:“gc()函数的作用只是提醒虚拟机:程序员希望进行一次垃圾回收。但是它不能保证垃圾回收一定会进行,而且具体什么时候进行是取决于具体的虚拟机的,不同的虚拟机有不同的对策。”
4.__metaclass__
![](http://img.blog.csdn.net/20140218222328640?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc2VjcmV0eA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
文档重点:默认使用的是type()创建一个类,当你指定__metaclass__了,就调用你指定的callable.那样你就可以自定义类的创建过程,__new__也可以自定义类创建过程,但是只能重写每个类,麻烦。
等价于
因为默认情况,如文档所言,就是用的type()去创建类Foo.你可以认为默认情况下,__new__是这样使用type()的
给个__metaclass__使用的例子,把某个类的所有属性,转成全大写
5.__call__
![](http://img.blog.csdn.net/20140218224257312?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc2VjcmV0eA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
当实现了这个方法时,这个类的实例(对象)可以当作函数一样调用。
比如类A实现了__call__(self, x), 那么
a = A()
a(x) #把a当函数使
6.__getattribute__和__getattr__
访问实例的属性时,__getattribute__无条件被调用,或者说无法阻止不被调用。当__getattribute__引发异常或者显示调用__getattr__时,方法__getattr__才能被调用。换句话理解:__getattribute__是正常取值,__getattr__是给前者兜底的,出了异常他负责背锅
先得明白一个道理:类,本身也是对象,类对象。这个同java,不难理解。实在不好想,就认为类对象存储在一个特殊地方,用虚拟机能理解的方式描述着类的定义。
这段文档,重点是:__new__用来创建类对象,实例化一个cls的类对象,表示这个类已经被加载了,解析了,现在可以拿着这个类创建普通实例对象了。如果类对象创建失败,则不会调用init方法,这个符合常理,类都没有,哪来的对象。其用处是:自定义方式创建类对象,比如改变这个类的属性等。类对象,类的对象是两个概念:见下例
class A(object):
x = 0
def __init__(self, xx=None):
if xx:
self.xx == xx
a = A(5)
print a.xx # a是A类的对象,A类的一个实例
print A.x # A是A类的类对象,描述了A类的类结构信息
那么__new__方法就是用来创建 A.x 一句中的A(A类的类对象),换句话说,是虚拟机用来加载类的。大部分情况下,你看不到它,你也不会直接或者间接调用它。
2.__init__
__init__学过OOP的都知道,构造函数。这个就是我们平常 a = A()一句会间接调用的函数。所以它应当在__new__之后被调用,要等__new__创建完类,才能根据类创建对象。
3.__del__
当对象将要被销毁时,__del__被调用。这个is about to(将要),虚拟机无法保证是什么具体时间点。需要注意一点:del x 并不是立即调用x.__del__(),仅仅是把x的引用计数器减少1。当某个对象的引用计数器为0时,表示对象不再被引用,也就是无法被访问到,也就是可以被垃圾回收了。
同java虚拟机一样,Python垃圾回收也是如此:当一个对象引用计数器为0,也不代表着立即被回收,而是等到下一次垃圾回收时,才会被回收。即使引用计数器为0,并且立即显示调用gc.collect()进行垃圾回收,也不是立即被回收,因为gc.collect()一句[ java中对应System.gc() ]执行,并不代表立即垃圾回收,而是说“垃圾回收已经排上日程了,将在接下来的一段时间内调用,具体接下来多久,虚拟机无法保证一个明确的数”。关于Java的System.gc(),这个描述比较恰当:“gc()函数的作用只是提醒虚拟机:程序员希望进行一次垃圾回收。但是它不能保证垃圾回收一定会进行,而且具体什么时候进行是取决于具体的虚拟机的,不同的虚拟机有不同的对策。”
4.__metaclass__
文档重点:默认使用的是type()创建一个类,当你指定__metaclass__了,就调用你指定的callable.那样你就可以自定义类的创建过程,__new__也可以自定义类创建过程,但是只能重写每个类,麻烦。
等价于
因为默认情况,如文档所言,就是用的type()去创建类Foo.你可以认为默认情况下,__new__是这样使用type()的
给个__metaclass__使用的例子,把某个类的所有属性,转成全大写
5.__call__
当实现了这个方法时,这个类的实例(对象)可以当作函数一样调用。
比如类A实现了__call__(self, x), 那么
a = A()
a(x) #把a当函数使
6.__getattribute__和__getattr__
访问实例的属性时,__getattribute__无条件被调用,或者说无法阻止不被调用。当__getattribute__引发异常或者显示调用__getattr__时,方法__getattr__才能被调用。换句话理解:__getattribute__是正常取值,__getattr__是给前者兜底的,出了异常他负责背锅
相关文章推荐
- python metaclass __new__ __init__ ___call__
- python中__init__()、__new__()、__call__()、__del__()几个魔法方法的用法
- python入门笔记(Day7)--slots,@property,MixIn,定制(str,iter,getitem,getattr,call)枚举(Enum)元type,metaclass,ORM
- 【原创】Python 对象创建过程中元类, __new__, __call__, __init__ 的处理
- python类中的__call__、__init__、__getattr__、__setattr__、__setattr__详解
- 详解Python中的__new__、__init__、__call__三个特殊方法
- python中的特殊函数__call__()以及init,setattr,getattr,delattr
- 飘逸的python - __new__、__init__、__call__傻傻分不清
- python __new__ __init__ __del__
- python __init__ __new__ __call__
- python:how does subclass call baseclass's __init__()
- Python 单例模式详解 __new__, import ,__dict__,__metaclass__
- 浅谈python中的__init__、__new__和__call__方法
- 飘逸的python - __new__、__init__、__call__傻傻分不清
- 理解python中的__str__, __call__, __init__, __getattr__
- Python Class __init__ __del__ 构造,析构过程解析【转】
- python中__init__、__getattr__、__setattr__、__call__的使用
- python中的__init__ 、__new__、__call__小结及使用
- 飘逸的python - __new__、__init__、__call__傻傻分不清
- python中__init__ ,__del__ &__new__