__new__ ,__init__和__del__
来源:互联网 发布:ssd优化软件 编辑:程序博客网 时间:2024/06/05 15:29
每个人都知道一个最基本的魔术方法, __init__
。通过此方法我们可以定义一个对象的初始操作。然而,当我调用 x =SomeClass()
的时候, __init__
并不是第一个被调用的方法。实际上,还有一个叫做 __new__
的方法,来构造这个实例。然后给在开始创建时候的初始化函数来传递参数。在对象生命周期的另一端,也有一个 __del__
方法。我们现在来近距离的看一看这三个方法:
__new__(cls, [...)
__new__
是在一个对象实例化的时候所调用的第一个方法。它的第一个参数是这个类,其他的参数是用来直接传递给 __init__
方法。 __new__
方法相当不常用,但是它有自己的特性,特别是当继承一个不可变的类型比如一个tuple或者string。我不希望在 __new__
上有太多细节,因为并不是很有用处,但是在 Python文档 中有详细的阐述。
__init__(self, […)
此方法为类的初始化方法。当构造函数被调用的时候的任何参数都将会传给它。(比如如果我们调用x = SomeClass(10, 'foo')
),那么 __init__
将会得到两个参数10和foo。 __init__
在Python的类定义中被广泛用到。
__del__(self)
如果 __new__
和 __init__
是对象的构造器的话,那么 __del__
就是析构器。它不实现语句 del x
(以上代码将不会翻译为 x.__del__()
)。它定义的是当一个对象进行垃圾回收时候的行为。当一个对象在删除的时需要更多的清洁工作的时候此方法会很有用,比如套接字对象或者是文件对象。注意,如果解释器退出的时候对象还存存在,就不能保证 __del__
能够被执行,所以 __del__
can’t serve as a replacement for good coding practices ()~~~~~~~
放在一起的话,这里是一个 __init__
和 __del__
实际使用的例子。
from os.path import joinclass FileObject: '''给文件对象进行包装从而确认在删除时文件流关闭''' def __init__(self, filepath='~', filename='sample.txt'): #读写模式打开一个文件 self.file = open(join(filepath, filename), 'r+') def __del__(self): self.file.close() del self.file
继承自object的新式类才有__new__
__new__至少要有一个参数cls,代表要实例化的类,此参数在实例化时由Python解释器自动提供
__new__必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以return父类__new__出来的实例,或者直接是object的__new__出来的实例
__init__有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值
例:
>>> class E(object):def __init__(self):print "init"def __new__(cls,*args,**kwargs):print "new %s"%clsreturn super(E, cls).__new__(cls, *args,**kwargs)>>> te = E()new <class '__main__.E'>init>>> >>> print type(te)<class '__main__.E'>或者
>>> class D(object):def __init__(self):print "init"def __new__(cls,*args,**kwargs):print "new %s"%clsreturn object.__new__(D,*args,**kwargs)>>> td = D()new <class '__main__.D'>init>>> print type(td)<class '__main__.D'>若__new__没有正确返回当前类cls的实例,那__init__是不会被调用的,即使是父类的实例也不行
>>> class B(object):def __init__(self):print "init">>> class C(object):def __init__(self):print "init"def __new__(cls,*args,**kwargs):print "new %s"%clsreturn object.__new__(B,*args,**kwargs)>>> tc = C()new <class '__main__.C'>>>> print type(tc)<class '__main__.B'>若没有继承object,也会自动创建对象,但不会执行本身的__new__方法,至于是否调用了object的__new__方法有待探究
>>> class G():def __init__(self):print "init"def __new__(cls,*args,**kwargs):print "new %s"%clsreturn object.__new__(G,*args,**kwargs)>>> tg = G()init>>> print type(tg)<type 'instance'>
>>> isinstance(tg,G)True
__new__ 的作用
依照Python官方文档的说法,__new__方法主要是当你继承一些不可变的class时(比如int, str, tuple), 提供给你一个自定义这些类的实例化过程的途径。还有就是实现自定义的metaclass。
首先我们来看一下第一个功能,具体我们可以用int来作为一个例子:
假如我们需要一个永远都是正数的整数类型,通过集成int,我们可能会写出这样的代码。
class PositiveInteger(int): def __init__(self, value): super(PositiveInteger, self).__init__(self, abs(value))i = PositiveInteger(-3)print i
但运行后会发现,结果根本不是我们想的那样,我们任然得到了-3。这是因为对于int这种 不可变的对象,我们只有重载它的__new__方法才能起到自定义的作用。
这是修改后的代码:
class PositiveInteger(int): def __new__(cls, value): return super(PositiveInteger, cls).__new__(cls, abs(value))i = PositiveInteger(-3)print i
通过重载__new__方法,我们实现了需要的功能。
另外一个作用,关于自定义metaclass。其实我最早接触__new__的时候,就是因为需要自定义 metaclass,但鉴于篇幅原因,我们下次再来讲python中的metaclass和__new__的关系。
用__new__来实现单例
事实上,当我们理解了__new__方法后,我们还可以利用它来做一些其他有趣的事情,比如实现 设计模式中的 单例模式(singleton) 。
因为类每一次实例化后产生的过程都是通过__new__来控制的,所以通过重载__new__方法,我们 可以很简单的实现单例模式。
class Singleton(object): def __new__(cls): # 关键在于这,每一次实例化的时候,我们都只会返回这同一个instance对象 if not hasattr(cls, 'instance'): cls.instance = super(Singleton, cls).__new__(cls) return cls.instanceobj1 = Singleton()obj2 = Singleton()obj1.attr1 = 'value1'print obj1.attr1, obj2.attr1print obj1 is obj2
输出结果:
value1 value1True
- __new__ ,__init__和__del__
- __new__ 和 __init__
- python __new__ 和 __init__
- python __new__和__init__
- Python __new__, __init__, __metaclass__, __call__, __del__, __getattr__, __getattribute__
- Python __init__和__del__方法
- Python中__new__() 和 __init__()
- python 中的 __new__ 和 __init__
- [深入Python]__new__和__init__
- __new__方法和__init__方法
- [深入Python]__new__和__init__
- python中__new__和__init__
- __new__和__init__的区别
- __new__和__init__的区别
- Python中的__init__和__new__
- python之__init__和__del__简单用法
- python __init__和__new__之间的区别
- python __init__和__new__之间的区别
- 携程大数据实时风控的架构及实践
- Codeforces 535D
- ELK5.3+Kafka集群配置
- 转载自http://www.jianshu.com/p/77e811e1c987
- 解决Flash Builder 4.7生成apk运行报错“UnsatisfiedLinkError”
- __new__ ,__init__和__del__
- 4 Values whose Sum is 0 POJ
- VMware vSphere 创建共享盘
- Linux的启动流程以及GRUB详解
- Java的四种引用,强弱软虚,用到的场景
- percona-toolkit 之 【pt-table-checksum】、【pt-table-sync】说明
- node 提示 module.js:471 throw err
- windows下安装pygame
- POJ-3268-Disease Management-(最短路径spfa)