__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. redis连接错误处理方案分享

    今天为了搞压测,定位是不是redis瓶颈. 在我们的服务器10.90.2.101上安装了一个redis,版本(redis-3.2.8.tar.gz),没有做任何配置,直接make & make ...

  2. 前端学PHP之面向对象系列第四篇-----关键字

    public public表示公有,它具有最大的访问权限,被定义为公有的类成员可以在任何地方被访问 如果属性用 var 定义,则被视为公有,如果方法没有设置关键字,则该方法默认为公有 <?php ...

  3. chrome flash

    chrome://settings/content/flash 在Chrome地址栏中输入:chrome://settings/content/flash,进入Flash设置,勾选允许网站运行flas ...

  4. laravel5.5的任务调度(定时任务)详解(demo)

    https://blog.csdn.net/LJFPHP/article/details/80417552 laravel5.5的定时任务详解(demo) 这篇文章写得挺详细的.看了它我基本就会用了 ...

  5. 关于Dubbo面试问题

    一.默认使用的是什么通信框架,还有别的选择吗? 默认也推荐使用netty框架,还有mina. 二.服务调用是阻塞的吗? 默认是阻塞的,可以异步调用,没有返回值的可以这么做. 三.一般使用什么注册中心? ...

  6. 【问题解决】docker中创建volume时,无访问权限

    挂载宿主机已存在目录后,在容器内对其进行操作,报"Permission denied". 可通过两种方式解决: 1> 关闭selinux. 临时关闭:# setenforce ...

  7. Ubuntu 14.10 下安装伪分布式hdoop 2.5.0

    折腾了一天,其间配置SSH时候出现了问题,误删了ssh-keygen相关文件,导致配置SSH彻底萎了,又重装了系统.... 采用伪分布式模式,即hadoop将所有进程运行于同一台主机上,但此时Hado ...

  8. Scala传名参数(By-Name)

    1.=> 在了解Scala的By-Name参数之前,先了解下“=>”在Scala中有几种用法: 1.对于值,“=>”相当于lambda表达式.如: scala> List(,, ...

  9. Recyclerview 实现上拉加载更多

    LinearLayoutManager layoutManager; layoutManager = new LinearLayoutManager(getActivity()); layoutMan ...

  10. [UE4]使用UFUNCTION注意事项

    #pragma once #include "CoreMinimal.h" #include "Blueprint/UserWidget.h" #include ...