一、__init__方法是什么
__init__方法通常用在初始化一个类实例的时候, class Person(object):
"""Silly Person""" def __init__(self, name, age):
print('__init__ called.')
self.name = name
self.age = age def __str__(self):
return '<Person: %s(%s)>' % (self.name, self.age) if __name__ == '__main__':
piglei = Person('piglei', 24)
print(piglei) """
__init__ called.
<Person: piglei(24)>
""" 二、 __new__方法是什么?
__new__方法接受的参数虽然也是和__init__一样,但__init__是在类实例创建之后调用,而__new__方法正是创建这个类实例的方法 class Person(object):
"""Silly Person""" def __new__(cls, name, age):
print('__new__ called.')
return super(Person, cls).__new__(cls) def __init__(self, name, age):
print('__init__ called.')
self.name = name
self.age = age def __str__(self):
return '<Person: %s(%s)>' % (self.name, self.age) if __name__ == '__main__':
piglei = Person('piglei', 24)
print(piglei) 执行结果
"""
__new__ called.
__init__ called.
<Person: piglei(24)>
"""
通过运行这段代码,我们可以看到,__new__方法的调用时发生在__init__之前的,其实当你实例化一个类的时候,具体的执行逻辑是这样的:
1 p=Person(name,age)
2 首先执行使用name和age参数来执行Person类的__new__方法,这个方法会返回Person类的一个实例(通常情况下是使用super(Persion,cls).__new__(cls)这样的方式)
3 然后利用这个实例来调用类的__init__方法,上一步里面__new__产生的实例也就是__init__里面的self
所以,__init__和__new__最主要的区别在于:
1 __init__通常用于初始化一个新实例,控制这个初始化的过程,比如添加一些属性,做一些额外的操作,发生在类实例被创建完以后,它是实例级别的方法
2 __new__通常用于控制生成一个新实例的过程。它是类级别的方法 三 __new__的作用
按照python官方文档的说法,__new__方法主要是当你继承一些不可变的class时(比如int,str,tuple),提供给你一个自定义这些类的实例化过程的途径,还有就是实现自定义的metaclass
首先来看一下第一个功能,我们用int来作为一个例子
假如我们需要一个永远都是正数的整数类型,通过集成int,我们可能会写出这样的代码 class PositiveInteger(int):
def __init__(self,value):
super(PositiveInteger, self).__init__() 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__来实现单例
事实上,我们理解了__new__方法后,我们可以用它来实现设计模式中的单例模式
因为类每一次实例化后产生的过程都是通过__new__来控制的,所以通过重载__new__方法,可以很简单的实现单例模式
class Singleton(object):
def __new__(cls, *args, **kwargs):
#每次实例化时,都会返回同一个instance对象
if not hasattr(cls,'instance'):
cls.instance=super(Singleton, cls).__new__(cls)
return cls.instance
obj1=Singleton()
obj2=Singleton() obj1.attr1='value1'
print(obj1.attr1,obj2.attr1)
print(obj1 is obj2)
"""
value1 value1
True
"""
obj1和obj2是同一个实例

__init__和__new__的更多相关文章

  1. python中的__init__ 、__new__、__call__小结

    这篇文章主要介绍了python中的__init__ .__new__.__call__小结,需要的朋友可以参考下 1.__new__(cls, *args, **kwargs)  创建对象时调用,返回 ...

  2. 详解python中的__init__与__new__方法

    一.__init__和__new__方法执行的顺序? 在面向对象中介绍了关于对象创建的过程,我们知道__new__方法先于__init__方法执行. 二.__new__方法是什么? 首先,我们先来看下 ...

  3. Python中的__init__和__new__

    一.__init__ 方法是什么? 使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,__init__ 方法通常用在初始化一个类实例的时候.例如: # -*- c ...

  4. 简析 __init__、__new__、__call__ 方法

    简析 __init__.__new__.__call__ 方法 任何事物都有一个从创建,被使用,再到消亡的过程,在程序语言面向对象编程模型中,对象也有相似的命运:创建.初始化.使 用.垃圾回收,不同的 ...

  5. python 的__init__ 和__new__ 区别

    在此介绍一下  __init__ 和  __new__ 先后调用的区别 代码如下: # __init__ 和 __new__的区别 # 通常在编代码时,__init__ 较为常见,但是__new__却 ...

  6. python中的__init__和__new__的区别

    一.__init__ 方法是什么?(init前后的线是双下划线) 使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,__init__ 方法通常用在初始化一个类实例 ...

  7. __init__、__new__、__call__ 方法

    __init__方法 __init__方法负责对象的初始化,系统执行该方法前,其实该对象已经存在了,要不然初始化什么东西呢?先看例子: # class A(object): python2 必须显示地 ...

  8. Python基础(十) __init__与__new__区别

    __init__与__new__区别: __init__在python,其实是,在实例化之后执行的,用来初始化一些属性,相当于构造函数,但是又不一样 细心一些,通过参数会有所发现,其实__init__ ...

  9. Python入门之面向对象的__init__和__new__方法

    Python入门之面向对象的__init__和__new__方法

  10. Python中__init__和__new__的区别详解

    __init__ 方法是什么? 使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,__init__ 方法通常用在初始化一个类实例的时候.例如: # -*- cod ...

随机推荐

  1. DatabaseFactory.CreateDatabase 方法操作数据库

    using Microsoft.Practices.EnterpriseLibrary.Data;using Microsoft.Practices.EnterpriseLibrary.Data.Sq ...

  2. js基础系列框架:JS重要知识点(转载)

    这里列出了一些JS重要知识点(不全面,但自己感觉很重要).彻底理解并掌握这些知识点,对于每个想要深入学习JS的朋友应该都是必须的. 讲解还是以示例代码搭配注释的形式,这里做个小目录: JS代码预解析原 ...

  3. linux 下安装svn服务

    鉴于在搭建时,参考网上很多资料,网上资料在有用的同时,也坑了很多人 本文的目的,也就是想让后继之人在搭建svn服务器时不再犯错,不再被网上漫天的坑爹作品所坑害,故此总结 /******开始****** ...

  4. CDH配置JAVA_HOME

    jdk成功安装 java -version 正确显示版本 echo $JAVA_HOME  正确输出路径 但CDH链接数据库还是报错: Error: JAVA_HOME is not set and ...

  5. 【转】Monkey测试4——Monkey命令行可用的全部选项

    Monkey命令行可用的全部选项 常规 --help 列出简单的用法. -v 命令行的每一个-v将增加反馈信息的级别. Level 0(缺省值)除启动提示.测试完成和最终结果之外,提供较少信息. Le ...

  6. 结果集(ResultSet)用法

    结果集(ResultSet)是数据中查询结果返回的一种对象,可以说结果集是一个存储查询结果的对象,但是结果集并不仅仅具有存储的功能,他同时还具有操纵数据的功能,可能完成对数据的更新等. 结果集读取数据 ...

  7. Working with JSON in C# & VB

    Introduction Whilst JSON is a compact and easy to read cross-language storage and data exchange form ...

  8. libevent在windows下用visual studio编译时出现error C2894错误的原因与解决方法

    libevent是一个使用很广泛的网络库,今天想了解下它.于是去git clone了一份源码,用vs2005的命令行:nmake -f makefile.nmake编译之,顺利编译通过,生成三个静态库 ...

  9. 服务器之ipmitool

    一般命令 raw #发送一个原始的IPMI请求,并且打印回复信息. Lan #配置网络(lan)信道(channel) chassis #查看底盘的状态和设置电源 event #向BMC发送一个已经定 ...

  10. hdu 4419 线段树 扫描线 离散化 矩形面积

    //离散化 + 扫描线 + 线段树 //这个线段树跟平常不太一样的地方在于记录了区间两个信息,len[i]表示颜色为i的被覆盖的长度为len[i], num[i]表示颜色i 『完全』覆盖了该区间几层. ...