写过python类的都会知道__init__,可能也了解__new__。我之前也了解__new__,但只做的它发生在__init__之前。其他的就比较模糊了

今天在学习单例模式时,看到有人用__new__去实例化,也有人用__init__去初始化,甚为奇怪,就查了一下别人的文章,总结一下。

简单来说,就是__new__负责返回一个实例,__init__负责初始化返回的那个实例,就是给返回的实例加上一些属性。__init__方法必须覆写,而__new__方法一般在__init__之前自动执行。如果__new__不能正确返回对象,__init__就不会调用,除非我们自己覆写了__new__,没有正确返回实例,否则不会出现这种情况。

例子来一发


class Human(object):
def __init__(self,n,a):
print "__init__ called"
self.name = n
self.age = a
def __new__(cls, name,age):
print "__new__ called"
return super(Human,cls).__new__(cls,name,age)
def tell(self):
print "My nama is %s,my age is %d"%(self.name,self.age) h = Human("lll",11) 输出:
_new__ called
__init__ called

这个就是我们经常用到的__init__,从输出结果显而易见,__new__先调用,__init__后调用。当我们去实例化一个对象时,基本过程是:

1.h = Human("lll",11)

2.有了第一步后,python解释器会立马去调用__new__,这个方法会返回一个Human的实例,并且给这个实例绑定了属性,这里就是name和age两个属性。方法的调用一般就是super(Human,cls).__new__(cls,name,age)这种格式。

3.__init__会接收到__new__返回的实例对象,和已经绑定的属性,然后给这些属性赋值,就是self.name = n ,self.age = a,给name属性赋值传递进来的n,age属性赋值传递进来的a。到此一个对象就建立完毕,可以用这个对象去调用其他方法了

所以__init__主要是用于初始化对象,给属性赋值,或者做一些比如print的事情,属于实例级别的方法__init__没有返回,__new__是生产一个实例,属于类级别的方法。__new__有返回值,返回新的对象。

刚才的__new__我们平时是不会去写出来的,属于自动调用。但是,有时候我们并不想让它去自动调用,就必须覆写它。

比如,如果我们的类继承自int,str,tuple这些类时,这些类是不可变的,所以在产生实例时他就是不可变的,但是我们继承了不可变的类又想让它可变,就只能去覆写它的__new__

比如我想判断一个数字是不是正数,就要继承int(可以保证是一个数字),然后在初始化中去判断,不是专门写一个函数去判断。

class ifPositive(int):
def __init__(self,value):
super(ifPositive,self).__init__(self,True if value>0 else False) i = ifPositive(3)
返回的是3,不是我们期待的1(此处不是返回True,是1,如果不是正数则返回0)

下面通过覆写__new__方法实现功能

class ifPositive(int):
def __new__(cls,value): 这里的第一个参数默认是cls
return super(ifPositive,cls).__new__(cls,True if value>0 else False) 此处一定要加return i = ifPositive(2)
返回1
i = ifPositive(-1)
返回0

查这两个方法时也看到__call__,此处也补充一下

一个类实现了这个函数,那么它的实例就多了一个功能,可以当作函数来用,直接在对象后面加上括号,里面就是__call__的参数,就会返回__call__方法的结果。还就拿上面的Human类,比如我给那个Human类加了一个方法

def __call__(self,attr):
if attr == "name":
return self.name
else:
return self.age h = Human("lll",11)
print h("name")
会返回“lll"

python __new__ __init__的更多相关文章

  1. python __new__ __init__ __del__

    1.python实例化顺序是.__new__ -->__init__ --> __del__ 2.如果重写new没return,就实例化不成功

  2. python __new__ __init__ 区别

    参数 __new__的第一个占位参数是class对象 __init__的第一个占位参数是class的实例对象 其他的参数应一致 作用 __new__ 用来创建实例,在返回的实例上执行__init__, ...

  3. python __new__以及__init__

    @[深入Python]__new__和__init__ 1 2 3 4 5 6 7 8 class A(object):     def __init__(self):         print & ...

  4. python中__init__.py文件的作用

    问题 在执行models.py时,报ImportError:No module named transwarp.db的错误,但明明transwarp下就有db.py文件,路径也没有错误.真是想不通.后 ...

  5. Python中__init__方法介绍

    本文介绍Python中__init__方法的意义.         __init__方法在类的一个对象被建立时,马上运行.这个方法可以用来对你的对象做一些你希望的 初始化 .注意,这个名称的开始和结尾 ...

  6. Python的__init__.py用法

    python中包的引入,对于大型项目中都会使用到这个功能,把实现不同功能的python文件放在一起,组成不同lib库,然后在其他地方调用. 包,python源文件+__init__.py 模块,pyt ...

  7. Python中__init__.py文件的作用详解

    转自http://www.jb51.net/article/92863.htm Python中__init__.py文件的作用详解 http://www.jb51.net/article/86580. ...

  8. 转载:【学习之家】Python中__init__.py文件的作用

    Python中__init__.py文件的作用详解 Python中__init__.py文件的作用详解 来源:学习之家 作者:xuexi110 人气:357 发布时间:2016-09-29 摘要:__ ...

  9. [深入Python]__new__和__init__

    class A(object): def __init__(self): print "init" def __new__(cls,*args, **kwargs): print ...

随机推荐

  1. PHP获取当前页面的网址

    PHP获取当前页面的网址 function GetCurUrl() { $url = 'http://'; if(isset($_SERVER['HTTPS']) AND $_SERVER['HTTP ...

  2. Ubuntu Eclipse ns3编译中 遇到的OSError 系列问题

    问题1:Permission denied 解决方法:修改文件权限,利用 chmod 命令 修改在 /home/wasdns/workspace/MyNS3_Mac/ns-3.25 (eclipse工 ...

  3. C# Int转Enum

    Int-->Enum (1)可以强制转换将整型转换成枚举类型. 例如:Colors color = (Colors)2 ,那么color即为Colors.Blue (2)利用Enum的静态方法T ...

  4. Hibernate 由实体类与配置文件的配置关系生成数据库中的表

    import org.hibernate.cfg.Configuration; import org.hibernate.tool.hbm2ddl.SchemaExport; public class ...

  5. 遇到Io阻塞时会切换任务之【爬虫版】

    #! /usr/bin/env python3 # -*- coding:utf- -*- from urllib import request import gevent,time from gev ...

  6. linux 多进程fork

    对于父进程,fork函数返回了子程序的进程号,而对于子程序,fork函数则返回零,这样,对于程序,只要判定fork函数的返回值,就知道自己是处于父进程还是子进程中.

  7. UTC和GMT时间辨析

    一.UTC和GMT 每个地区都有自己的本地时间,在网上以及无线电通信中时间转换的问题就显得格外突出. 整个地球分为二十四时区,每个时区都有自己的本地时间.在国际无线电通信场合,为了统一起见,使用一个统 ...

  8. EsayUI + MVC + ADO.NET(仓储基础接口)

      1.RepositoryFramework(仓储接口:无外乎就是CRUD) 1.IAddRepository(添加接口) using System; namespace Notify.Infras ...

  9. 一步一步实现JS拖拽插件

    js拖拽是常见的网页效果,本文将从零开始实现一个简单的js插件. 一.js拖拽插件的原理 常见的拖拽操作是什么样的呢?整过过程大概有下面几个步骤: 1.用鼠标点击被拖拽的元素 2.按住鼠标不放,移动鼠 ...

  10. Codeforces 832D - Misha, Grisha and Underground

    832D - Misha, Grisha and Underground 思路:lca,求两个最短路的公共长度.公共长度公式为(d(a,b)+d(b,c)-d(a,c))/2. 代码: #includ ...