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)

正如以上所示,一个类可以有多个位置参数和多个命名参数,而在实例化开始之后,在调用 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)。

使用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 实例化方法_Python中__new__()方法的使用和实例化相关推荐

  1. python中 普通方法_python中普通方法classmethod和staticmethod的区别与用法

    class Foo(object): #实例方法,第一个承诺书必须是实例对象,一般习惯用self. def ins_m(self): print("是类{}的实例方法,只能被实例调用&quo ...

  2. python里的join方法_python中join()方法介绍

    描述 Python join() 方法用于将序列中的元素以指定的字符连接生成一个新的字符串. 语法 join()方法语法: str . join ( sequence ) 参数 sequence -- ...

  3. new to python什么意思_Python中__new__的作用

    __new__ 的作用 依照Python官方文档的说法,__new__方法主要是当你继承一些不可变的class时(比如int, str, tuple), 提供给你一个自定义这些类的实例化过程的途径.还 ...

  4. python获取方法的装饰方法_python中的方法和装饰器

    [TOC] 装饰器 python中的装饰器(decorator)是在pep 318中被首次引入,它的本质是一个函数这个函数是接受其它参数为参数,并且用一个新的,修改后的函数作为替换,最常见的装饰器就c ...

  5. python decode方法_Python中decode()方法有哪些功能?

    摘要: 下文讲述Python中decode()的方法的功能简介说明,如下所示: decode()方法功能: 使用指定编码格式对bytes对象进行解码, 缺省编码格式为"utf-8" ...

  6. python中readlines方法_Python中readlines()方法有哪些功能?

    摘要: 下文讲述Python中readlines()的方法的功能简介说明,如下所示: readlines()方法功能: 用于读取整个文件中所有行,并放入一个列表中 (每一行为列表中的一个元素) rea ...

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

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

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

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

  9. python中常见的双下方法_python中常见的双下方法_python面向对象(5)__特殊双下方法...

    双下方法 双下方法是开发python这个语言程序员用的,源码中使用的. 我们不能轻易使用双下方法.可能重新写object的源码,慎用!!! 双下方法特征:你不知道干啥了,就会触发某个双下方法 len ...

最新文章

  1. jsp ul设置滚动条_jquery实现Li滚动时滚动条自动添加样式的方法
  2. 为你的水晶报表装载本地图片
  3. 学python心得体会500字-Python初学心得体会
  4. 探索Android中的Parcel机制(上)
  5. linux打包压缩命令汇总
  6. [ACM] hdu 1228 A+B (字符串处理)
  7. linux常规检查命令,linux学习-常规命令使用5
  8. 获取Class类对象的三种方式
  9. 买书(信息学奥数一本通-T1293)
  10. 团队开发中Git冲突解决
  11. 聚类算法实践——谱聚类、Chameleon聚类
  12. PWA登陆iOS了,但它还有这些缺陷
  13. 谷歌/微软/必应web页面免费翻译插件
  14. VMware 找不到我的计算机
  15. 单片机学习笔记(持续更新中)
  16. 金蝶KIS专业版V14.1下载链接,金蝶KIS专业版V14.1新增功能介绍 安装包下载地址
  17. 打印1000年到2000年之间的闰年
  18. VSCode中设置大小写转换的快捷键
  19. Excel会计应学35招秘技
  20. ceres_solver解PnP平差问题、Matlab数据制作

热门文章

  1. countanddown java_Java多线程之CountDownLatch
  2. img 居中_解决img标签下方出现的小空隙
  3. Linux错误27,解决在linux下编译32程序出现“/usr/include/gnu/stubs.h:7:27: 致命错误:gnu/stubs-32.h:没有那个文件或目录问题”...
  4. git分支开发常用命令
  5. mysql故障切换_MySQL故障切换笔记之应用无感知设计详解
  6. 中班音乐活动 机器人_幼儿园中班音乐活动教案《机器人》
  7. linux运行欧陆风云,Arm linux启动分析(1)
  8. mysql修改字段结构_MySQL修改表结构及其添加删除修改字段功能
  9. 11.2.0.2的SPM的一个bug
  10. oracle查看表空间的内容,学习笔记:Oracle查看object对象 表空间 表 索引 数据文件的使用空间...