Python中的常用的__方法
__new__、__init__、__call__的介绍
在讲到使用元类创建单例模式之前,比需了解__new__这个内置方法的作用,在上面讲元类的时候我们用到了__new__方法来实现类的创建。然而我在那之前还是对__new__这个方法和__init__方法有一定的疑惑。因此这里花点时间对其概念做一次了解和区分。
__new__ 创建新对象
__new__方法负责创建一个实例对象,在对象被创建的时候调用该方法它是一个类方法。__new__方法在返回一个实例之后,会自动的调用__init__方法,对实例进行初始化。如果__new__方法不返回值,或者返回的不是实例,那么它就不会自动的去调用__init__方法。
__init__ 实例化
__init__ 方法负责将该实例对象进行初始化,在对象被创建之后调用该方法,在__new__方法创建出一个实例后对实例属性进行初始化。__init__方法可以没有返回值。
__call__ 调用
__call__方法其实和类的创建过程和实例化没有多大关系了,定义了__call__方法才能被使用函数的方式执行。
例如: class A(object): def __call__(self): print "__call__ be called" a = A() a() #输出 #__call__ be called
打个比方帮助理解:如果将创建实例的过程比作建一个房子。
- 那么class就是一个房屋的设计图,他规定了这个房子有几个房间,每个人房间的大小朝向等。这个设计图就是累的结构
- __new__就是一个房屋的框架,每个具体的房屋都需要先搭好框架后才能进行专修,当然现有了房屋设计才能有具体的房屋框架出来。这个就是从类到类实例的创建。
- __init__就是装修房子的过程,对房屋的墙面和地板等颜色材质的丰富就是它该做的事情,当然先有具体的房子框架出来才能进行装饰了。这个就是实例属性的初始化,它是在__new__出一个实例后才能初始化。
- __call__就是房子的电话,有了固定电话,才能被打电话嘛(就是通过括号的方式像函数一样执行)。
#coding:utf-8 class Foo(object): def __new__(cls, *args, **kwargs): #__new__是一个类方法,在对象创建的时候调用 print "excute __new__" return super(Foo,cls).__new__(cls,*args,**kwargs) def __init__(self,value): #__init__是一个实例方法,在对象创建后调用,对实例属性做初始化 print "excute __init" self.value = value f1 = Foo(1) print f1.value f2 = Foo(2) print f2.value #输出===: excute __new__ excute __init excute __new__ excute __init #====可以看出new方法在init方法之前执行
子类如果重写__new__方法,一般依然要调用父类的__new__方法。
class Child(Foo): def __new__(cls, *args, **kwargs): return suyper(Child, cls).__new__(cls, *args, **kwargs)
必须注意的是,类的__new__方法之后,必须生成本类的实例才能自动调用本类的__init__方法进行初始化,否则不会自动调用__init__.
class Foo(object): def __init__(self, *args, **kwargs): print "Foo __init__" def __new__(cls, *args, **kwargs): return object.__new__(Stranger, *args, **kwargs) class Stranger(object): def __init__(self,name): print "class Stranger's __init__ be called" self.name = name foo = Foo("test") print type(foo) #<class '__main__.Stranger'> print foo.name #AttributeError: 'Stranger' object has no attribute 'name' #说明:如果new方法返回的不是本类的实例,那么本类(Foo)的init和生成的类(Stranger)的init都不会被调用
原创作者:马一特
文章出处:http://www.cnblogs.com/mayite/
版权声明:自由转载-非商用-非衍生-保持署名
(创意共享4.0许可证)
转载说明:如果文章对您有帮助,欢迎点赞,评论加转载,赠人玫瑰,手留余香
浙公网安备 33010602011771号