提到构造器,大家都会想到 __init__,那么__new__是什么?也是构造器。

init 构造器

都很熟悉了,直接上代码

class MyClass(object):
def __init__(self):
pass def m1(self):
print(3) mc = MyClass()
mc.m1() # 3

是不是很简单

别急,请跟着我的思路,方法m1的参数有个self,这个self就是实例,在调用m1之前这个实例肯定已经产生了;但是init的参数也有个self,在调用init之前,我们并没有实例化,那这个self从何而来呢?new生成的。

new 构造器

1. new 和 init 一样都是类的构造器

2. new在init之前执行,即使没有显示定义

3. new 必须有返回对象,这个对象就是该类的实例,或者父类的实例(该类继承了一个类),并且是new出来的实例,这个实例的就是self,也就是该类的实例化对象。

4. new生成的self传给init,如果没有正确返回实例,init将不会执行。

5. new可以自定义

6. new是类方法,需要显示的传入类cls作为第一个参数,至少要有这个参数

7. 新式类中才有new

8. new和init共用参数,也就是说二者参数形式要一致

几个例子来验证上面8条。

代码1

class A(object):
def __init__(self,a):
print "init"
self.a=a
def __new__(cls,*args, **kwargs):
print "new %s"%cls
print('args:', args)
return object.__new__(cls, *args, **kwargs) # 返回当前类的实例 aa=A(3)
# new <class '__main__.A'>
# ('args:', (3,))
# init
print(aa) # <__main__.A object at 0x026FC4B0>
print(aa.a) # 3 self.a

1. 新式类,经典类我试了,不行,new没有运行,但不会报错

2. new 比 init 先执行

3. new 和 init 共用了参数3

4. new 返回了当前类的实例,new出来的

代码2

class inch(float):
def __new__(cls, arg=0.0): # cls 相当于 self
print(1)
return float.__new__(cls, arg * 0.0254)
def __init__(self, aa):
print('aa:', aa)
print(2) a = inch(12) # new 和 init 公用了参数12
#
# ('aa:', 12)
#
print(a) # 返回的实例就是new的return,父类的实例 float(12*0.0254)
# 0.3048 =12*0.0254

1. 该类继承了float类

2. new 返回了父类float的实例

3. 该类实例化后其实是new 返回的实例,也就是float(12*0.0254)

代码3

class inch2(float):
def __new__(cls, arg=0.0): # cls 相当于 self
print(11)
return float.__new__(cls, arg)*0.0254 # 返回了父类的实例*0.0254
def __init__(self,aa):
print(22) # 这句没有被执行,因为new没有正确返回父类的实例 a = inch2(12)
#
print(a)
# 0.3048 =12*0.0254

new没有正确返回父类的实例,导致init没有被执行。

类的构造器-init和new的更多相关文章

  1. 类的构造器[constructor]_C#

    类的构造器(constructor): 1.       先看两个类定义: class A{ } 相当于: class A: object { Public A ( ) : base( ) {   } ...

  2. Java8自定义函数式编程接口和便捷的引用类的构造器及方法

    什么是函数编程接口? 约束:抽象方法有且只有一个,即不能有多个抽象方法,在接口中覆写Object类中的public方法(如equal),不算是函数式接口的方法. 被@FunctionalInterfa ...

  3. Scala类的构造器与访问器

    1.构造器 在Scala中,每个类都有一个主构造器.主构造器与类的定义交织在一起,如下: class Person ( private var _name: String, private var _ ...

  4. 方法引用_通过this引用本类的成员方法和方法引用_类的构造器(构造方法)引用和数组的构造器引用

    package com.yang.Test.ThisMethodReference; /** * 通过this引用本类的成员方法 */ public class Husband { //定义一个买房子 ...

  5. java使用this关键字调用本类重载构造器

    在构造器中可以调用本类的其他重载构造器,不能使用构造器名称来调用另一个构造器,而是应该使用Java特定的this(-.)来调用. this(-.)方法必须出现在构造器中的第一行,用来调用其他重载构造器 ...

  6. Python10/22--面向对象编程/类与对象/init函数

    类: 语法: class关键字 类名# 类名规范 大写开头 驼峰命名法class SHOldboyStudent: # 描述该类对象的特征 school = "上海Oldboy" ...

  7. Scala基础:类和构造器

    类 package com.zy.scala.cls /** * 在 Scala 中,类并不用声明为 public 类型的. * Scala 源文件中可以包含多个类,所有这些类都具有共有可见性. */ ...

  8. Java 类的构造器中this()和super()的困惑

    关于构造器中super的使用,书本上这样写: “super是指向父类的引用,如果构造方法没有显示地调用父类的构造方法,那么编译器会自动为它加上一个默认的super()方法调用.如果父类由没有默认的无参 ...

  9. 第2节 Scala中面向对象编程:1、类的定义;2、类的构造器;3、object和伴生对象;4、apply和main方法

    6.    类.对象.继承.特质 Scala的类与Java.C++的类比起来更简洁,学完之后你会更爱Scala!!! 6.1.   类 6.1.1.    类的定义 package cn.itcast ...

随机推荐

  1. EasyUI相关知识点整理

    EasyUI相关知识整理 EasyUI是一种基于jQuery.Angular..Vue和React的用户界面插件集合.easyui为创建现代化,互动,JavaScript应用程序,提供必要的功能.也就 ...

  2. idea下maven下载插件慢问题

    在pom.xml中添加maven 依赖包时,我就发现不管是否用了FQ,下载速度都好慢,就1M的东西能下半天,很是苦恼,于是到网上搜资料,然后让我查到了.说是使用阿里的maven镜像就可以了.我于是亲自 ...

  3. Virtual DOM 和 diff 算法

    virtual DOM : virtual DOM 用 js 模拟 DOM 结构,用 js 来对比前后变化,提高重绘性能. diff: 比如在 git 中,如果用命令  git diff xxx文件 ...

  4. Machine Learning--week3 逻辑回归函数(分类)、决策边界、逻辑回归代价函数、多分类与(逻辑回归和线性回归的)正则化

    Classification It's not a good idea to use linear regression for classification problem. We can use ...

  5. Vue的介绍及基础指令

    一.什么是Vue Vue.js是一个渐进式 JavaScript 框架 通过对框架的了解与运用程度,来决定其在整个项目中的应用范围,最终可以独立以框架方式完成整个web前端项目 为什么要学习Vue 三 ...

  6. null与undefined的区别

    null和undefined是JavaScript五种基本数据类型中的两种. null是一个特殊值,但我们常常误解它,有时候我们会把它和另一个数据类型undefined的含义互相混淆. 首先我们来了解 ...

  7. Monent.js:强大的日期处理类库

    一.介绍及安装 1.1 介绍 Moment.js是一个优秀的JavaScript 日期处理类库. 如果没有Moment.js之类的日期处理库,我们如果需要获得格式化后的日期.往往需要通过new Dat ...

  8. 启动xampp出错,Port 80 in use by "Unable to open process" with PID 4!

    启动xampp出错,Port 80 in use by "Unable to open process" with PID 4! 环境:windows10 80端口被PID为4的应 ...

  9. js中实现截取数组的后几个元素作为一个新数组的方法

    有时候我们会遇到这种需求,截取数组中后5个元素作为一个新数组,且顺序不能变.数组中的slice()方法和splice()方法都可以实现这样的操作. const arr = [1,2,7,2,6,0,3 ...

  10. URL URI

    URL 是统一资源定位符,对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址.互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理 ...