一、__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. hMailServer 附件大小限制

    修改php.ini文件 1.post_max_size = 10M 表单提交最大数据为10M.此项不是限制上传单个文件的大小,而是针对整个表单的提交数据进行限制的. 2.file_uploads = ...

  2. python c example2:pylame2

    #include <Python.h> #include <lame.h> //pyton object variables typedef struct{ PyObject_ ...

  3. Android Notification使用方法

    1.http://www.cnblogs.com/plokmju/p/android_Notification.html 2.http://blog.csdn.net/vipzjyno1/articl ...

  4. Servlet 客户端 HTTP 请求

    当浏览器请求网页时,它会向 Web 服务器发送特定信息,这些信息不能被直接读取,因为这些信息是作为 HTTP 请求的头的一部分进行传输的.您可以查看 HTTP 协议 了解更多相关信息. 以下是来自于浏 ...

  5. 【JavaEE】Springmvc+Spring+Hibernate整合及example

    前面两篇文章,分别介绍了Springmvc和Spring的搭建方法,本文再搭建hibernate,并建立SSH最基本的代码结构. Hibernate和前面两个比就比较复杂了,Hibernate是一个o ...

  6. C#中4种深拷贝方法介绍

    1:利用反射实现 public static T DeepCopy<T>(T obj) {   //如果是字符串或值类型则直接返回   if (obj is string || obj.G ...

  7. Unity如何判断网络连接类型

    今天遇到了一个问题,如何判断手机游戏当前的网络连接类型,是wifi还是234G? 起初准备在Android中写好插件供Unity调用,后来在网上浏览众神的帖子时,在csdn上看到了使用NetworkR ...

  8. C++中计算矩阵的行列式

    使用eigen库: 求行列式: #include <iostream> #include <Eigen/Dense> using namespace std; using na ...

  9. Laravel5.1 模型初探

    Laravel的模型也是访问数据库的,它更加面向对象,一个模型对应着一张表 我们可以使用模型对数据做一些增删改查的操作. 1 创建模型 创建模型是可以使用Artisan控制台的: php artisa ...

  10. CodeIgniter框架——函数(时间函数、装载函数)剖析+小知识点

    连接数据库: 格式: mysql -h主机地址 -u用户名-p用户密码 数据库的提示符:mysql> 退出数据库: exit(回车) 知识点积累: 1.date_default_timezone ...