Python中__new__()方法的使用和实例化

  • 1
  • 2

new()是在新式类中新出现的方法,它作用在构造方法init()建造实例之前,可以这么理解,在Python 中存在于类里面的构造方法init()负责将类的实例化,而在init()调用之前,new()决定是否要使用该init()方法,因为new()可以调用其他类的构造方法或者直接返回别的对象来作为本类 的实例。 
如果将类比喻为工厂,那么init()方法则是该工厂的生产工人,init()方法接受的初始化参 数则是生产所需原料,init()方法会按照方法中的语句负责将原料加工成实例以供工厂出货。而 new()则是生产部经理,new()方法可以决定是否将原料提供给该生产部工人,同时它还决定着出 货产品是否为该生产部的产品,因为这名经理可以借该工厂的名义向客户出售完全不是该工厂的产品。 
new()方法的特性: 
new()方法是在类准备将自身实例化时调用。 
new()方法始终都是类的静态方法,即使没有被加上静态方法装饰器。

类的实例化和它的构造方法通常都是这个样子:

class MyClass(object):def __init__(self, *args, **kwargs):...
# 实例化
myclass = MyClass(*args, **kwargs)
  • 1
  • 2
  • 3
  • 4
  • 5

正如以上所示,一个类可以有多个位置参数和多个命名参数,而在实例化开始之后,在调用 init()方法之前,Python首先调用new()方法:

def __new__(cls, *args, **kwargs):...
  • 1
  • 2

第一个参数cls是当前正在实例化的类。 
如果要得到当前类的实例,应当在当前类中的new()方法语句中调用当前类的父类 的new()方法。 
例如,如果当前类是直接继承自object,那当前类的new()方法返回的对象应该为:

def __new__(cls, *args, **kwargs):...return object.__new__(cls)
  • 1
  • 2
  • 3

事实上如果(新式)类中没有重写new()方法,即在定义新式类时没有重新定义new()时 ,Python默认是调用该类的直接父类的new()方法来构造该类的实例,如果该类的父类也没有重写 new(),那么将一直按此规矩追溯至object的new()方法,因为object是所有新式类的基类。 
而如果新式类中重写了new()方法,那么你可以自由选择任意一个的其他的新式类(必定要是 新式类,只有新式类必定都有new(),因为所有新式类都是object的后代,而经典类则没有new() 方法)的new()方法来制造实例,包括这个新式类的所有前代类和后代类,只要它们不会造成递归死 循环。具体看以下代码解释:

class Foo(object):def __init__(self, *args, **kwargs):...def __new__(cls, *args, **kwargs):return object.__new__(cls, *args, **kwargs)    # 以上return等同于
# return object.__new__(Foo, *args, **kwargs)
# return Stranger.__new__(cls, *args, **kwargs)
# return Child.__new__(cls, *args, **kwargs)class Child(Foo):def __new__(cls, *args, **kwargs):return object.__new__(cls, *args, **kwargs)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

#如果Child中没有定义new()方法,那么会自动调用其父类的new()方法来制造实例,即

Foo.__new__(cls, *args, **kwargs)
  • 1

在任何新式类的new()方法,不能调用自身的new()来制造实例,因为这会造成死循环。因此必须避免类似以下的写法: 
在Foo中避免:return Foo.new(cls, *args, **kwargs)或return cls.new(cls, *args, **kwargs)。

使用object或者没有血缘关系的新式类的new()是安全的,但是如果是在有继承关系的两个类之间,应避免互调造成死循环,例如:(Foo)return Child.new(cls), (Child)return Foo.new(cls)。

class Stranger(object):...
  • 1
  • 2

在制造Stranger实例时,会自动调用 object.new(cls) 
通常来说,新式类开始实例化时,new()方法会返回cls(cls指代当前类)的实例,然后该类的 init()方法作为构造方法会接收这个实例(即self)作为自己的第一个参数,然后依次传入new ()方法中接收的位置参数和命名参数。

注意:如果new()没有返回cls(即当前类)的实例,那么当前类的init()方法是不会被调用 的。如果new()返回其他类(新式类或经典类均可)的实例,那么只会调用被返回的那个类的构造方 法。

class Foo(object):def __init__(self, *args, **kwargs):...def __new__(cls, *args, **kwargs):return object.__new__(Stranger, *args, **kwargs)  class Stranger(object):...foo = Foo()
print type(foo)  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

打印的结果显示foo其实是Stranger类的实例。

因此可以这么描述new()和ini()的区别,在新式类中new()才是真正的实例化方法,为类提供外壳制造出实例框架,然后调用该框架内的构造方法init()使其丰满。 
如果以建房子做比喻,new()方法负责开发地皮,打下地基,并将原料存放在工地。而init()方法负责从工地取材料建造出地皮开发招标书中规定的大楼,init()负责大楼的细节设计,建造,装修使其可交付给客户。

Python中__new__()方法的使用和实例化

2016年10月12日 17:35:43

阅读数:8883

 本篇文章转载自网络。
  • 1
  • 2

new()是在新式类中新出现的方法,它作用在构造方法init()建造实例之前,可以这么理解,在Python 中存在于类里面的构造方法init()负责将类的实例化,而在init()调用之前,new()决定是否要使用该init()方法,因为new()可以调用其他类的构造方法或者直接返回别的对象来作为本类 的实例。 
如果将类比喻为工厂,那么init()方法则是该工厂的生产工人,init()方法接受的初始化参 数则是生产所需原料,init()方法会按照方法中的语句负责将原料加工成实例以供工厂出货。而 new()则是生产部经理,new()方法可以决定是否将原料提供给该生产部工人,同时它还决定着出 货产品是否为该生产部的产品,因为这名经理可以借该工厂的名义向客户出售完全不是该工厂的产品。 
new()方法的特性: 
new()方法是在类准备将自身实例化时调用。 
new()方法始终都是类的静态方法,即使没有被加上静态方法装饰器。

类的实例化和它的构造方法通常都是这个样子:

class MyClass(object):def __init__(self, *args, **kwargs):...
# 实例化
myclass = MyClass(*args, **kwargs)
  • 1
  • 2
  • 3
  • 4
  • 5

正如以上所示,一个类可以有多个位置参数和多个命名参数,而在实例化开始之后,在调用 init()方法之前,Python首先调用new()方法:

def __new__(cls, *args, **kwargs):...
  • 1
  • 2

第一个参数cls是当前正在实例化的类。 
如果要得到当前类的实例,应当在当前类中的new()方法语句中调用当前类的父类 的new()方法。 
例如,如果当前类是直接继承自object,那当前类的new()方法返回的对象应该为:

def __new__(cls, *args, **kwargs):...return object.__new__(cls)
  • 1
  • 2
  • 3

事实上如果(新式)类中没有重写new()方法,即在定义新式类时没有重新定义new()时 ,Python默认是调用该类的直接父类的new()方法来构造该类的实例,如果该类的父类也没有重写 new(),那么将一直按此规矩追溯至object的new()方法,因为object是所有新式类的基类。 
而如果新式类中重写了new()方法,那么你可以自由选择任意一个的其他的新式类(必定要是 新式类,只有新式类必定都有new(),因为所有新式类都是object的后代,而经典类则没有new() 方法)的new()方法来制造实例,包括这个新式类的所有前代类和后代类,只要它们不会造成递归死 循环。具体看以下代码解释:

class Foo(object):def __init__(self, *args, **kwargs):...def __new__(cls, *args, **kwargs):return object.__new__(cls, *args, **kwargs)    # 以上return等同于
# return object.__new__(Foo, *args, **kwargs)
# return Stranger.__new__(cls, *args, **kwargs)
# return Child.__new__(cls, *args, **kwargs)class Child(Foo):def __new__(cls, *args, **kwargs):return object.__new__(cls, *args, **kwargs)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

#如果Child中没有定义new()方法,那么会自动调用其父类的new()方法来制造实例,即

Foo.__new__(cls, *args, **kwargs)
  • 1

在任何新式类的new()方法,不能调用自身的new()来制造实例,因为这会造成死循环。因此必须避免类似以下的写法: 
在Foo中避免:return Foo.new(cls, *args, **kwargs)或return cls.new(cls, *args, **kwargs)。

使用object或者没有血缘关系的新式类的new()是安全的,但是如果是在有继承关系的两个类之间,应避免互调造成死循环,例如:(Foo)return Child.new(cls), (Child)return Foo.new(cls)。

class Stranger(object):...
  • 1
  • 2

在制造Stranger实例时,会自动调用 object.new(cls) 
通常来说,新式类开始实例化时,new()方法会返回cls(cls指代当前类)的实例,然后该类的 init()方法作为构造方法会接收这个实例(即self)作为自己的第一个参数,然后依次传入new ()方法中接收的位置参数和命名参数。

注意:如果new()没有返回cls(即当前类)的实例,那么当前类的init()方法是不会被调用 的。如果new()返回其他类(新式类或经典类均可)的实例,那么只会调用被返回的那个类的构造方 法。

class Foo(object):def __init__(self, *args, **kwargs):...def __new__(cls, *args, **kwargs):return object.__new__(Stranger, *args, **kwargs)  class Stranger(object):...foo = Foo()
print type(foo)  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

打印的结果显示foo其实是Stranger类的实例。

因此可以这么描述new()和ini()的区别,在新式类中new()才是真正的实例化方法,为类提供外壳制造出实例框架,然后调用该框架内的构造方法init()使其丰满。 
如果以建房子做比喻,new()方法负责开发地皮,打下地基,并将原料存放在工地。而init()方法负责从工地取材料建造出地皮开发招标书中规定的大楼,init()负责大楼的细节设计,建造,装修使其可交付给客户。

转载于:https://www.cnblogs.com/armyochen/p/9032977.html

__new__()方法的使用和实例化相关推荐

  1. python 实例化方法_Python中__new__()方法的使用和实例化

    new()是在新式类中新出现的方法,它作用在构造方法init()建造实例之前,可以这么理解,在Python 中存在于类里面的构造方法init()负责将类的实例化,而在init()调用之前,new()决 ...

  2. python函数实例化_Python中的__new__()方法与实例化

    __new__()是在新式类中新出现的方法,它作用在构造方法建造实例之前,可以这么理解,在Python 中 存在于类里面的构造方法__init__()负责将类的实例化,而在__init__()启动之前 ...

  3. python构造方法new_Python 之 __new__() 方法与实例化(转)

    _new__() 是在新式类中新出现的方法,它作用在构造方法建造实例之前,可以这么理解,在 Python 中存在于类里面的构造方法 __init__() 负责将类的实例化,而在 __init__() ...

  4. [Python] Python 之 __new__() 方法与实例化

    __new__() 是在新式类中新出现的方法,它作用在构造方法建造实例之前,可以这么理解,在 Python 中存在于类里面的构造方法 __init__() 负责将类的实例化,而在 __init__() ...

  5. python单例模式基于__new__方法实现的单例模式(推荐使用,方便)

    单例模式以及Python实现 单例模式 单例模式就是确保一个类只有一个实例.当你希望整个系统中,某个类只有一个实例时,单例模式就派上了用场. 比如,某个服务器的配置信息存在在一个文件中,客户端通过Ap ...

  6. python中__init__和__new__方法的使用

    1.__new__方法默认返回实例对象供__init__方法.实例方法使用. 2.__init__方法为初始化方法,为类的实例提供一些属性或完成一些动作. 3.__new__方法创建实例对象供__in ...

  7. python怎么创建方法_python中的__new__方法

    print(obj) #打印结果:<__main__.Foo object at 0x000002636FEAA208> 事实上如果(新式)类中没有重写__new__()方法,即在定义新式 ...

  8. python 多继承 __new___Python3中的__new__方法以及继承不可变类型类的问题

    最近在学到Python中的__new__方法时被弄懵逼了,一开始实在是很难理解,有很多地方想不通(本人强迫症).最近自己慢慢思索得出了能说服自己的理解: 说__new__方法之前要先提到__init_ ...

  9. Python中的__new__()方法的使用

    __new__() 函数只能用于从object继承的新式类. 先看下object类中对__new__()方法的定义: class object:   @staticmethod # known cas ...

最新文章

  1. 基于TableStore的数据采集分析系统介绍
  2. [BZOJ 5093]图的价值
  3. python合并pdf 加书签_Python生成pdf目录书签的实例方法
  4. matlab max与min获取矩阵最大最小值函数
  5. 详细介绍一下 Smoke Testing(冒烟测试)
  6. 每天10个Linux命令一
  7. matlab怎么算方差和标准差,matlab怎么求矩阵的均值和标准差 看完你就知道了
  8. Hive之同比环比的计算
  9. 计算机程序是指为解决某一问题,在计算机中为解决某一特定问题二设计的指令程序是...
  10. python中执行py文件出错(提示File “stdin”,line 1,SyntaxError:invalid syntax)
  11. 计算机网络 | 网络层(数据平面)
  12. 暴风魔镜 光标漂移_如何防止光标在游戏过程中漂移到另一个监视器
  13. 汽车门把手的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  14. 一个项目的流程和前期的准备工作
  15. VB 数据库交互(二)——经典五实例总结
  16. PowerBI:关于PBIX,PBIT及PBIDS
  17. 运维工程师历年企业笔试真题汇总
  18. CLIP-Adapter:利用Adapter微调CLIP适配下游任务
  19. ISD1760语音输出到LM4890语音放大效果可能不明显。
  20. ssl证书的含义是什么,ssl证书有什么作用

热门文章

  1. protocol buffer java_Protocol Buffer Java实例
  2. Python入门--字符串的查询操作,find,rfind,index,rindex
  3. 最小生成树的java实现
  4. 2019蓝桥杯A组:数列求值(递推式)
  5. PBR理论基础3:基于图像的光照(上)
  6. bzoj 4417: [Shoi2013]超级跳马(矩阵合并+快速幂)
  7. bzoj 1056 1862: [Zjoi2006]GameZ游戏排名系统(Treap+Hash)
  8. 斯特林公式--求n!的位数
  9. matlab不用循环,三维矩阵按横切页(垂直于纸面且)向右展开为2维,即(i,j,:)展开。将二维矩阵每行顺序不变依次向左复制,如:(a,b,c)复制为(a,a,a,b,b,b,c,c,c)
  10. k8s中的endpoint