__new__ 的作用

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

首先我们来看一下第一个功能,具体我们可以用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

通过重载__new__方法,我们实现了需要的功能。

另外一个作用,关于自定义metaclass。其实我最早接触__new__的时候,就是因为需要自定义 metaclass,但鉴于篇幅原因,我们下次再来讲python中的metaclass和__new__的关系。

用__new__来实现单例

事实上,当我们理解了__new__方法后,我们还可以利用它来做一些其他有趣的事情,比如实现 设计模式中的 单例模式(singleton) 。

因为类每一次实例化后产生的过程都是通过__new__来控制的,所以通过重载__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

print obj1 is obj2

输出结果:

value1 value1

True

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

Python中__new__的作用的更多相关文章

  1. [py]python中__new__作用

    元类metaclass 使劲搞,但是没搞清楚__new__的作用 了解Python元类 Python进阶:一步步理解Python中的元类metaclass Python中的__new__和__init ...

  2. Python中__new__方法为什么有人说是构造方法?有什么作用?

    __new__方法是Python新式类引入的,通常用于控制生成一个新实例的过程.它是类级别的静态方法,是在创建实例对象前执行,如果自定义类中没有重写该方法,则Python自动调用父类的方法,当所有父类 ...

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

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

  4. 关于Python中迭代器的作用

    迭代器的定义:含有__iter__()方法和__next__()方法的就是迭代器,即(iterate) 含有__iter__()方法就可以使用for循环,即iterable(可迭代的) Iterabl ...

  5. Python中__new__与__init__介绍

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

  6. python中的 * 和 ** 作用含义

    python中的 * 和 ** ,能够让函数支持任意数量的参数,它们在函数定义和调用中,有着不同的目的 一. 打包参数 * 的作用:在函数定义中,收集所有位置参数到一个新的元组,并将整个元组赋值给变量 ...

  7. [问与答]Python 中 __all__ 的作用 ?

    你要是看Python的源码或者相关框架的源码,总是在 __init__.py 或者是源文件的开头看到一个 __all__ 变量的定义,今天就说说它的作用. orangleliu 问题出处 Can so ...

  8. python中 __new__和__init__

    python这两个函数和类的实例化有关. __init__是实例化完成之后调用的,会对生成的对象实例做一些修饰 __new__是python新类型才有的,它更像是c/c++里面的构造函数,因为这个函数 ...

  9. Python 中__new__()和__init__()的区别

    转自: https://blog.csdn.net/weixin_37579123/article/details/89515577 __new__方法:类级别的方法 特性: 1.是在类准备将自身实例 ...

随机推荐

  1. 通过IOCTL_ATA_PASS_THROUGH访问ATA设备接口

    控制代码功能:像ATA硬盘发送ATA指令.IDE/ATA:接口,一个串行,一个并行,一般叫做IDE接口的硬盘和ATA接口的硬盘.ATA指令:可以操作ATA硬盘的指令. typedef struct _ ...

  2. 【java_需阅读】Java中static关键字用法总结

    1.     静态方法 通常,在一个类中定义一个方法为static,那就是说,无需本类的对象即可调用此方法 声明为static的方法有以下几条限制: · 它们仅能调用其他的static 方法. · 它 ...

  3. Speeding Up The Traveling Salesman Using Dynamic Programming

    Copied From:https://medium.com/basecs/speeding-up-the-traveling-salesman-using-dynamic-programming-b ...

  4. android利用provider查询同一个数据库中没有对外暴露出来的表

    [原创]转载请加本篇博客地址http://www.cnblogs.com/scarecrow-blog/p/6266042.html 个人感觉这是android provider 的一个漏洞, 废话少 ...

  5. 固态硬盘SSD,机械硬盘HDD,4K速度对比。

    HDD - SSD -

  6. plsql 创建表空间、用户、赋予权限

    plsql 创建表空间.用户.赋予权限 --用户名:testuser --密码:bzhs!*6 --1.创建表空间--用SYSTEM用户登陆数据库,执行下面语句创建表空间CREATE TABLESPA ...

  7. 【nginx】之proxy_pass

    在nginx中配置proxy_pass代理转发时,如果在proxy_pass后面的url加/,表示绝对根路径:如果没有/,表示相对路径,把匹配的路径部分也给代理走.     假设下面四种情况分别用 h ...

  8. 【AMQ】之JMS概念

    1.JMS(Java Message Service)Java消息服务,是Java20几种技术其中之一 2.JMS规范定义了Java中访问消息中间件的接口,但是没有给实现,这个实现就是由第三方使用者来 ...

  9. LeetCode——5.Longest Palindromic Substring

    一.题目链接:https://leetcode.com/problems/longest-palindromic-substring/ 二.题目大意: 给定一个字符串,找出它最长的回文子串.例如,字符 ...

  10. redis 主从复制 [转]

    一.Redis的Replication: 这里首先需要说明的是,在Redis中配置Master-Slave模式真是太简单了.相信在阅读完这篇Blog之后你也可以轻松做到.这里我们还是先列出一些理论性的 ...