概述

  __new__() 是在新式类中新出现的方法,在 Python 中类实例化时,__new__()方法用在 __init__() 启动之前,决定是否要使用该 __init__() 方法,因为__new__() 可以调用其他类的构造方法或者直接返回别的对象来作为本类的实例。
特性总结:

  1. __new__()方法是类在准备实例化时调用,也就是实例化之前。
  2. __new__()方法始终都是类的静态方法,即使没有加上静态方法装饰器。

示例1:

def __new__(cls,*args,**kwargs):
...
return object.__new__(cls)

注意:

  事实上如果(新式)类中没有重写__new__()方法,即在定义新式类时没有重新定义__new__()时,Python默认是调用该类的直接父类的__new__()方法来构造该类的实例,如果该类的父类也没有重写__new__(),那么将一直按此规矩追溯至object的__new__()方法,因为object是所有新式类的基类。

强化进阶

  网上有个很赞的比喻:如果将类比喻为工厂,那么__init__()方法则是该工厂的生产工人,__init__()方法接受的初始化参数则是生产所需原料,__init__()方法会按照方法中的语句负责将原料加工成实例以供工厂出货。而__new__()则是生产部经理,__new__()方法可以决定是否将原料提供给该生产部工人,同时它还决定着出货产品是否为该生产部的产品,因为这名经理可以借该工厂的名义向客户出售完全不是该工厂的产品。

示例2:

 #!/usr/bin/env python
#-*- coding:utf-8 -*- class A(object):
static_var = "withClass" def __init__(self):
self.hostname = "MySql"
self.user = "root" def mod_user(self,name):
self.user = name def putongMethed(self):
print "普通方法:putongMethod" @property
def property_var(self):
return "property_var" @staticmethod
def static_method():
print "静态方法:StaticMethod" @classmethod
def class_method(cls):
print "类方法:ClassMethod" class B(A):
def __new__(cls, *args, **kwargs):
print "实例化前的类对象:%s"%cls
print "实例化前的类参数:%s"%cls.__dict__
#在这里,B为A的派生类,A为B的基类,调用基类A的__new__()方法,并指向A的__init__()构造函数。
return A.__new__(A,*args,**kwargs) if __name__=="__main__":
obj = B()
print "类对象的静态字段:%s"%B.static_var
B.static_method()
B.class_method()
print "类属性:%s" % obj.property_var
print "实例对象: %s"%obj
obj.putongMethed()
print "实例对象的参数:%s"%obj.__dict__
#__new__()仅指定实例构造方法__init__(),并不执行该方法初始化实例
obj.__init__()
print "执行__init__()初始化的参数:%s"%obj.__dict__
#调用A类中的方法
obj.mod_user("mysql")
print "调用A类方法修改普通字段: %s"%obj.__dict__

狸猫换太子

结果:

类对象:<class '__main__.B'>
实例化前的类参数:{'__module__': '__main__', '__new__': <staticmethod object at 0x022E7230>, '__doc__': None}
类对象的静态字段:withClass
静态方法:StaticMethod
类方法:ClassMethod
类属性:property_var
实例对象: <__main__.A object at 0x022E72D0>
普通方法:putongMethod
实例对象的参数:{}
执行__init__()初始化的参数:{'hostname': 'MySql', 'user': 'root'}
调用A类方法修改普通字段: {'hostname': 'MySql', 'user': 'mysql'}

示例解读:

  1. 经理(__new__())借该工厂(B)的名义向客户(obj)出售完全不是该工厂的产品(A的__init__()以及A类指针)。
  2. 我们可以看到A类的静态字段,静态方法,类方法都被B类完美继承,可以通过B.xxMethod获得。
  3. obj=B()实例化时,得到的实例对象的指针却指向了A类,这就是__new__()狸猫换太子,借B工厂将他的父类A给打包出售了。
  4. 因为obj的类指针指向了A,所以可以调用A的普通方法,这是如果调用B类中的普通方法或静态字段时,就会报错!!
  5. obj.__dict__()查看实例对象中的参数,发现为空,没错,这里__new__()只是给了个地址(A和A.__init__()的地址),初始化需要手动执行。
  6. 收到执行obj.__init__()函数后,读取实例对象参数,就得到了A类下的__init__()的数据结构。

类实例化过程

实例对象(独有的命名空间)= 指向类对象的指针 + 普通字段

新式类__new__()方法的更多相关文章

  1. 第8.7节 Python类__new__方法和构造方法关系深入剖析:__new__方法执行结果对__init__的影响案例详解

    一. 引言 前面章节介绍了类中的构造方法和__new__方法,并分析了二者执行的先后顺序关系.__new__方法在__init__方法前执行,__new__方法执行后才返回实例对象,也就是说__new ...

  2. p3新式类__new__使用和实例化

    嗯,new方法返回的是一个全新的对象是真正在内存中分配的内存地址 示例1·class Foo(object): # __metaclass__ = MyType def __init__(self, ...

  3. 类 __new__方法实现单例

    继承了单例的类,子类也是单例模式

  4. Python中__new__方法为什么有人说是构造方法?有什么作用?

    __new__方法是Python新式类引入的,通常用于控制生成一个新实例的过程.它是类级别的静态方法,是在创建实例对象前执行,如果自定义类中没有重写该方法,则Python自动调用父类的方法,当所有父类 ...

  5. 新式类 VS 经典类

    一.概述 Python中支持多继承,也就是一个子类可以继承多个父类/基类.当一个调用一个自身没有定义的属性时,它是按照何种顺序去父类中寻找的呢?尤其是当众多父类中都包含有同名的属性,这就涉及到新式类 ...

  6. python之新式类与经典类

    经典类与新式类 经典类:P 或 P()--深度查找,向上查父节点 新式类 :P(object)---广度查找,继承object,新式类的方法较多  

  7. python中的__new__与__init__,新式类和经典类(2.x)

    在python2.x中,从object继承得来的类称为新式类(如class A(object))不从object继承得来的类称为经典类(如class A()) 新式类跟经典类的差别主要是以下几点: 1 ...

  8. python开发学习-day07(面向对象之多态、类的方法、反射、新式类and旧式类、socket编程)

    s12-20160227-day07 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: ...

  9. python2中的__new__与__init__,新式类和经典类-乾颐堂

    在python2.x中,从object继承得来的类称为新式类(如class A(object))不从object继承得来的类称为经典类(如class A()) 新式类跟经典类的差别主要是以下几点: 1 ...

随机推荐

  1. Mybatis 动态SQL注解 in操作符的用法

    在SQL语法中如果我们想使用in的话直接可以像如下一样使用: ,,) ; ,,) ; 但是如果在MyBatis中的使用 in 操作符,像下面这样写的话,肯定会报错: @Update("upd ...

  2. 关于button的onclientclick事件和onclick事件

    利用onclientclick事件在onclick事件之前执行,对用户输入文本进行检查,如果不符合规定则retrun false JS代码 function check() { var aLength ...

  3. Angular4的dom事件

    Angular4的dom事件 差值表达式和属性绑定其实是一样的(例) <!-- 这两个是一样的效果,使用哪个都可以 --> <img src="{{imgUrl}}&quo ...

  4. 004_linux驱动之_class_create创建一个设备类

    (一)解析:class_create函数和class_destroy函数     创建一个类         和        删除一个类.   (二)class_create函数原型   struc ...

  5. CF #589 (Div. 2) D. Complete Tripartite 构造

    这个 D 还是十分友好的~ 你发现这 $3$ 个集合形成了一个环的关系,所以随意调换顺序是无所谓的. 然后随便让 $1$ 个点成为第 $2$ 集合,那么不与这个点连边的一定也属于第二集合. 然后再随便 ...

  6. luogu 4768

    kruskal 重构树对于一张无向图,我们在进行 kruskal 的过程中每当合并两个联通块时新建虚拟节点 t对于两个联通块的根节点 fau,fav 连无向边(fau, t),(fav, t) 其中点 ...

  7. sigprocmask , sigpending 和 sigsuspend函数

    转自 http://blog.csdn.net/elbort/article/details/7594772 sigprocmask函数:功能描述:设定对信号屏蔽集内的信号的处理方式(阻塞或不阻塞). ...

  8. 什么是CSR

    CSR的全称是Certificate Signing Request. 是我们在申请Https证书是向CA所提供的一杯申请书.其内部储存了我们申请证书所需要的基本信息.它是一个经过Base64编码的纯 ...

  9. gitlab 配置.ssh实现免密登陆

    首次配置gitlab的.ssh时 安装gitbash 通过gitbash 配置.ssh 打开gitbash,输入如下命令生成ssh,邮箱换成自己的 ssh-keygen -t rsa -C " ...

  10. DSSM算法-计算文本相似度

    转载请注明出处: http://blog.csdn.net/u013074302/article/details/76422551 导语 在NLP领域,语义相似度的计算一直是个难题:搜索场景下quer ...