_new__() 是在新式类中新出现的方法,它作用在构造方法建造实例之前,可以这么理解,在 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)

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

def __new__(cls, *args, **kwargs):

...

第一个参数cls是当前正在实例化的类。

如果要得到当前类的实例,应当在当前类中的 __new__() 方法语句中调用当前类的父类的 __new__() 方法。

例如,如果当前类是直接继承自 object,那当前类的 __new__() 方法返回的对象应该为:

def __new__(cls, *args, **kwargs):

...

return object.__new__(cls)

注意:

事实上如果(新式)类中没有重写__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)

# 如果Child中没有定义__new__()方法,那么会自动调用其父类的__new__()方法来制造实例,即 Foo.__new__(cls, *args, **kwargs)。

# 在任何新式类的__new__()方法,不能调用自身的__new__()来制造实例,因为这会造成死循环。因此必须避免类似以下的写法:

# 在Foo中避免:return Foo.__new__(cls, *args, **kwargs)或return cls.__new__(cls, *args, **kwargs)。Child同理。

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

class Stranger(object):

...

# 在制造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)

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

# 因此可以这么描述__new__()和__ini__()的区别,在新式类中__new__()才是真正的实例化方法,为类提供外壳制造出实例框架,然后调用该框架内的构造方法__init__()使其丰满。

# 如果以建房子做比喻,__new__()方法负责开发地皮,打下地基,并将原料存放在工地。而__init__()方法负责从工地取材料建造出地皮开发招标书中规定的大楼,__init__()负责大楼的细节设计,建造,装修使其可交付给客户。

python构造方法new_Python 之 __new__() 方法与实例化(转)相关推荐

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

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

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

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

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

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

  4. python什么时候要构造方法init_Python之类方法、__new__方法和__init__方法介绍

    在编程语言中创建一个类,有构造方法这样的一个术语.而在Python中,通常大家都认为__init__是构造方法,其实并不完全等同.在构建类中,有一个特殊的方法__new__,这个才能等同为构造方法. ...

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

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

  6. python new方法_Python中的__new__()方法的使用

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

  7. 面向对象—的__new__()方法详解

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

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

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

  9. __new__()方法的使用和实例化

    Python中__new__()方法的使用和实例化 1 2 new()是在新式类中新出现的方法,它作用在构造方法init()建造实例之前,可以这么理解,在Python 中存在于类里面的构造方法init ...

最新文章

  1. Data source rejected establishment of connection, message from server: Too many connections
  2. WPF的ProgressBar进度条
  3. 全连接条件随机场_CRF条件随机场
  4. ASP.NET (C#开发环境)Request对象 之 ServerVariables集合
  5. 杭电1072 猜数字
  6. Script:列出没有主键或唯一索引的表
  7. extjs初学者教程
  8. 计算机硬件安装装置,一种计算机硬件教学装置制造方法及图纸
  9. 三大变换与自控(二)傅里叶级数的复数形式推导
  10. 汉洛塔问题(c解决)
  11. 翻译管理协作翻译平台-crowdin
  12. 如何开发一个酷炫的mdx
  13. Linux重启命令shutdown与reboot
  14. app测试-monkey
  15. C# BBP公式计算π
  16. 内蒙古大学计算机考研复试分数线,内蒙古大学2013-2014考研复试分数线.docx
  17. 设计模式总结干货(很好链接站点,见解深刻,易理解入门)
  18. 湖南大学夏令营 ---- 信息科学与工程学院
  19. pandas保存csv乱码
  20. c语言打地鼠项目报告,打地鼠实训报告.docx

热门文章

  1. python接口测试面试_面试秘籍 | 一文搞定面试中接口测试问题
  2. Flink的窗口聚合操作(Time\Count Window)
  3. agaular 离线文档_Zeal 国外一款面向开发者的离线文档查看工具
  4. 直播笔记 | Unity中射线检测详解
  5. Unity2018新功能抢鲜 | C# Job System Ⅱ
  6. 怎么画闭合线_骨骺线闭合怎么长高
  7. linux命令中xargs,在Linux上使用xargs命令的详细教程
  8. Chrome 将逐步阻止浏览器中的混合内容下载
  9. 经典论坛程序 Discuz! 回归
  10. 你是否为类编写接口?我乞求你停下!