首先__new__() 函数只能用于从object继承的新式类;其次,object将__new__()方法定义为静态方法,并且至少需要传递一个参数cls,cls表示需要实例化的类,此参数在实例化时由Python解释器自动提供。

下面,看一个关于__init__和__new__的例子:

class Person(object):
def __new__(cls, name, age):
print('%s:__new__ called.' %name)
return super(Person, cls).__new__(cls) def __init__(self, name, age):
self.name=name
self.age = age
print('%s:__init__ called.' %name) def __str__(self):
return self.name if __name__ == '__main__':
ming = Person('ming', 24)
print(ming)

执行结果:

ming:__new__ called.
ming:__init__ called.
ming

通过运行这段代码,我们可以看到,__new__方法的调用是发生在__init__之前的。

总结:

  1.__init__ 通常用于初始化一个新实例,控制这个初始化的过程,比如添加一些属性, 做一些额外的操作,发生在类实例被创建完以后。它是实例级别的方法。
  2.__new__ 通常用于控制生成一个新实例的过程。它是类级别的方法。
那么,我们一般什么时候会用到__new__方法呢?

1、当我们在继承一些不可变的类时(比如int, str, tuple),我们可以通过这个方法自定义这些不可变类的实例化过程。

我们用int类来举例:

  假如我们需要一个永远都是正数的整数类型,可以通过继承int类,然后可能会写出这样的代码:

class PositiveInteger(int):
def __init__(self, value):
super(PositiveInteger, self).__init__(self, abs(value)) i = PositiveInteger(-3)
print i

  运行后发现该还是-3,这是因为int是不可变类型,所以这个时候就需要重载__new__()方法,才能起到自定义的作用:

class PositiveInteger(int):
def __new__(cls, value):
return super(PositiveInteger, cls).__new__(cls, abs(value)) i = PositiveInteger(-3)
print i

2、可以用__new__()方法来实现单例:

class Singleton(object):
def __new__(cls):
# 关键在于这,每一次实例化的时候,我们都只会返回这同一个instance对象
if not hasattr(cls, 'instance'):
cls.instance = super(Singleton, cls).__new__(cls)
return cls.instance obj1 = Singleton()
obj2 = Singleton()
obj1.attr1 = 'value1' print(obj1.attr1, obj2.attr1) #value1 value1
print(obj1 is obj2) #True

可以看出obj1和obj2是同一个实例。

pyhton中的__new__和__init__的更多相关文章

  1. Python中的__new__和__init__

    Python中的__new__和__init__ 写了这么多的class,现在才知道还有个__new__方法, 那么它和__init__有什么区别呢? class TestCls(): "& ...

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

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

  3. python 中的__new__与__init__

    在Python中的class中有两个方法__new__与__init__,有什么区别呢? class TestCls(): """docstring for TestCl ...

  4. python中的__new__、__init__和__del__

    __new__.__init__.__del__三个方法用于实例的创建和销毁,在使用python的类中,我们最常用的是__init__方法,通常称为构造方法,__new__方法几乎不会使用,这篇文章是 ...

  5. Python 中的__new__和__init__的区别

    [同] 二者均是Python面向对象语言中的函数,__new__比较少用,__init__则用的比较多. [异] __new__是在实例创建之前被调用的,因为它的任务就是创建实例然后返回该实例对象,是 ...

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

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

  7. 详解Python中的__new__、__init__、__call__三个特殊方法(zz)

    __new__: 对象的创建,是一个静态方法,第一个参数是cls.(想想也是,不可能是self,对象还没创建,哪来的self)__init__ : 对象的初始化, 是一个实例方法,第一个参数是self ...

  8. 一个案例深入Python中的__new__和__init__

    准备 在Python中,一切皆对象. 既然一切皆对象,那么类也是对象,我们暂且称之为 类对象.来个简单例子(本篇文章的所有案例都是运行在Python3.4中): class foo(): pass p ...

  9. __new__、__init__、__call__三个特殊方法

    用双下划线包围的特殊方法在Python中又被成为魔术方法,类似于C++等语言中的构造函数,这里我们就来详解Python中的__new__.__init__.__call__三个特殊方法: 1.__ne ...

随机推荐

  1. dubbo 使用 filter 报错解决

    dubbo可以用filter实现类似tomcat filter过滤器. 实现1.接口请求时间监控. 2.打印输入输出日志(输出日志有应用自己决定) 配置时出现报错. No such extension ...

  2. Robot FrameWork基础学习(三)

    一.关键字(Keyword)根据架构的区分可分为以下三层结构: 底层关键字.公共层关键字.特性关键字. 底层关键字一般与最底层的代码在关系,为上层公共关键字和特性关键字提供接口. 公共层关键字:一般是 ...

  3. CodeForces - 767C Garland 树的遍历

    C. Garland time limit per test 2 seconds memory limit per test 256 megabytes input standard input ou ...

  4. E20190414-hm

    ease  n. 安逸; 容易; 轻松,舒适; 不拘束,自在; (for/with ease of) repetition n. 重复,反复; 背诵; 复制品,副本; [乐] 复唱,复奏,重奏; gl ...

  5. jquery冲突的关键字nodeName、nodeValue和nodeType!

    原文:http://blog.csdn.net/hdfyq/article/details/52805836 [缘由]在工作流数据库设计的时候,  都节点管理的功能.  结果有2个字段为  NODE_ ...

  6. mysql之SQL入门与提升(一)

    一.基本的增删改查 1.1首先建一张表 DROP TABLE IF EXISTS `websites`;CREATE TABLE `websites` ( `id` int(11) NOT NULL ...

  7. NEERC2017:L - Laminar Family

    传送门 很容易想到,离线按路径长度从大到小排个序,用树链剖分加颗支持区间cover的线段树就好了 代码: #include<cstdio> #include<iostream> ...

  8. android okhttp和webview session共享

    public static OkHttpClient get(Context context){ OkHttpClient.Builder builder = new OkHttpClient.Bui ...

  9. 当前View的坐标相对其他View的位置坐标

    // 将rect由rect所在视图转换到目标视图view中,返回在目标视图view中的rect - (CGRect)convertRect:(CGRect)rect toView:(UIView *) ...

  10. jave之set和get的用法

    package com.xxl.api.admin; public class Test { private int score; public int getScore() { return sco ...