新式类__new__()方法
概述
__new__() 是在新式类中新出现的方法,在 Python 中类实例化时,__new__()方法用在 __init__() 启动之前,决定是否要使用该 __init__() 方法,因为__new__() 可以调用其他类的构造方法或者直接返回别的对象来作为本类的实例。
特性总结:
- __new__()方法是类在准备实例化时调用,也就是实例化之前。
- __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'}
示例解读:
- 经理(__new__())借该工厂(B)的名义向客户(obj)出售完全不是该工厂的产品(A的__init__()以及A类指针)。
- 我们可以看到A类的静态字段,静态方法,类方法都被B类完美继承,可以通过B.xxMethod获得。
- obj=B()实例化时,得到的实例对象的指针却指向了A类,这就是__new__()狸猫换太子,借B工厂将他的父类A给打包出售了。
- 因为obj的类指针指向了A,所以可以调用A的普通方法,这是如果调用B类中的普通方法或静态字段时,就会报错!!
- obj.__dict__()查看实例对象中的参数,发现为空,没错,这里__new__()只是给了个地址(A和A.__init__()的地址),初始化需要手动执行。
- 收到执行obj.__init__()函数后,读取实例对象参数,就得到了A类下的__init__()的数据结构。
类实例化过程
实例对象(独有的命名空间)= 指向类对象的指针 + 普通字段

新式类__new__()方法的更多相关文章
- 第8.7节 Python类__new__方法和构造方法关系深入剖析:__new__方法执行结果对__init__的影响案例详解
一. 引言 前面章节介绍了类中的构造方法和__new__方法,并分析了二者执行的先后顺序关系.__new__方法在__init__方法前执行,__new__方法执行后才返回实例对象,也就是说__new ...
- p3新式类__new__使用和实例化
嗯,new方法返回的是一个全新的对象是真正在内存中分配的内存地址 示例1·class Foo(object): # __metaclass__ = MyType def __init__(self, ...
- 类 __new__方法实现单例
继承了单例的类,子类也是单例模式
- Python中__new__方法为什么有人说是构造方法?有什么作用?
__new__方法是Python新式类引入的,通常用于控制生成一个新实例的过程.它是类级别的静态方法,是在创建实例对象前执行,如果自定义类中没有重写该方法,则Python自动调用父类的方法,当所有父类 ...
- 新式类 VS 经典类
一.概述 Python中支持多继承,也就是一个子类可以继承多个父类/基类.当一个调用一个自身没有定义的属性时,它是按照何种顺序去父类中寻找的呢?尤其是当众多父类中都包含有同名的属性,这就涉及到新式类 ...
- python之新式类与经典类
经典类与新式类 经典类:P 或 P()--深度查找,向上查父节点 新式类 :P(object)---广度查找,继承object,新式类的方法较多
- python中的__new__与__init__,新式类和经典类(2.x)
在python2.x中,从object继承得来的类称为新式类(如class A(object))不从object继承得来的类称为经典类(如class A()) 新式类跟经典类的差别主要是以下几点: 1 ...
- python开发学习-day07(面向对象之多态、类的方法、反射、新式类and旧式类、socket编程)
s12-20160227-day07 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: ...
- python2中的__new__与__init__,新式类和经典类-乾颐堂
在python2.x中,从object继承得来的类称为新式类(如class A(object))不从object继承得来的类称为经典类(如class A()) 新式类跟经典类的差别主要是以下几点: 1 ...
随机推荐
- canvas制图学习
<!DOCTYPE html> <html lang="zh-en"> <head> <meta charset="UTF-8& ...
- Nginx中ngx_http_log_module模块
指定⽇日志格式记录请求指令: access_log设置缓冲⽇日志写⼊入的路路径,格式和配置Syntax: access_log path [format[buffer=size] [gzip[=lev ...
- Vue结合后端DjangoFramework的在线生鲜超市(前后端分离)【django2.2+xadmin+ueditor】
在线博客教程:https://www.cnblogs.com/Eric15/category/1300432.html https://www.cnblogs.com/derek1184405959/ ...
- airflow--调度研究
1.从调度到airflow ETL,是英文 Extract,Transform,Load 的缩写,用来描述将数据从来源端经过抽取(extract).转换(transform).加载(load)至目的端 ...
- 8、Spring Boot 2.x 服务器部署
1.8 服务器部署 完整源码: Spring-Boot-Demos 1.8.1 jar包提取出来maven打包(避免每次重复打相同的jar包),pom.xml配置如下: <build> & ...
- Codeforces Round #583 (Div. 1 + Div. 2, based on Olympiad of Metropolises) C题
C. Bad Sequence Problem Description: Petya's friends made him a birthday present — a bracket sequenc ...
- 007_STM32程序移植之_多通道ADC转换
1. 测试环境:STM32C8T6 2. 测试:使用DMA进行多通道ADC转换 3. 描述:用 ADC 连续采集 12 路模拟信号,并由 DMA 传输到内存.ADC 配置为扫描 并且连续转换模式,AD ...
- HTML的基础
HTML:超文本标记语言 超文本包括:文字.图片.音频.视频.动画等 流程:写好HTML代码后通过浏览器(自动编译HTML代码)展现出效果 HTM ...
- CSP-S 模拟测试94题解
T1 yuuustu: 可以对两边取对数,然后就转化为两个double的比较,时间复杂度$O(n)$ 然后我就用神奇0.4骗分水过 #include<bits/stdc++.h> usin ...
- python3.5+win7 安装 numpy 和scipy的总结
1.安装numpy. 官网下载numpy.下载地址为https://pypi.Python.org/pypi/numpy.选择与Python版本相对应的numpy版本.之后在python35 ...