类的构造器-init和new
提到构造器,大家都会想到 __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的更多相关文章
- 类的构造器[constructor]_C#
类的构造器(constructor): 1. 先看两个类定义: class A{ } 相当于: class A: object { Public A ( ) : base( ) { } ...
- Java8自定义函数式编程接口和便捷的引用类的构造器及方法
什么是函数编程接口? 约束:抽象方法有且只有一个,即不能有多个抽象方法,在接口中覆写Object类中的public方法(如equal),不算是函数式接口的方法. 被@FunctionalInterfa ...
- Scala类的构造器与访问器
1.构造器 在Scala中,每个类都有一个主构造器.主构造器与类的定义交织在一起,如下: class Person ( private var _name: String, private var _ ...
- 方法引用_通过this引用本类的成员方法和方法引用_类的构造器(构造方法)引用和数组的构造器引用
package com.yang.Test.ThisMethodReference; /** * 通过this引用本类的成员方法 */ public class Husband { //定义一个买房子 ...
- java使用this关键字调用本类重载构造器
在构造器中可以调用本类的其他重载构造器,不能使用构造器名称来调用另一个构造器,而是应该使用Java特定的this(-.)来调用. this(-.)方法必须出现在构造器中的第一行,用来调用其他重载构造器 ...
- Python10/22--面向对象编程/类与对象/init函数
类: 语法: class关键字 类名# 类名规范 大写开头 驼峰命名法class SHOldboyStudent: # 描述该类对象的特征 school = "上海Oldboy" ...
- Scala基础:类和构造器
类 package com.zy.scala.cls /** * 在 Scala 中,类并不用声明为 public 类型的. * Scala 源文件中可以包含多个类,所有这些类都具有共有可见性. */ ...
- Java 类的构造器中this()和super()的困惑
关于构造器中super的使用,书本上这样写: “super是指向父类的引用,如果构造方法没有显示地调用父类的构造方法,那么编译器会自动为它加上一个默认的super()方法调用.如果父类由没有默认的无参 ...
- 第2节 Scala中面向对象编程:1、类的定义;2、类的构造器;3、object和伴生对象;4、apply和main方法
6. 类.对象.继承.特质 Scala的类与Java.C++的类比起来更简洁,学完之后你会更爱Scala!!! 6.1. 类 6.1.1. 类的定义 package cn.itcast ...
随机推荐
- qemu 对虚机的地址空间管理
转载:http://huchh.com/2015/06/22/qemu-%E5%AF%B9%E8%99%9A%E6%9C%BA%E7%9A%84%E7%BA%BF%E6%80%A7%E5%9C%B0% ...
- web api使用JObject接收时,报“无法创建抽象类”错误
https://bbs.csdn.net/topics/391952288 在下列函数中增加 ModelBinders.Binders.Add(typeof(JObject), new JObjec ...
- Python数据分析Pandas库数据结构(一)
pandas数据结构 1.生成一维矩阵模拟数据 import pandas as pdimport numpy as nps = pd.Series([1,2,3,4,np.nan,9,9])s2 = ...
- Tomcat报错: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/myApp]]
Tomcat报错:严重: A child container failed during startjava.util.concurrent.ExecutionException: org.apach ...
- rangeOfString 和 containsString 兼容iOS7处理
//查找字符串是否包含"心" NSString *str = @"每天都有好心情"; if ([str containsString:@"心" ...
- Ansible在Ubuntu上的安装
#apt安装 apt-get install software-properties-common apt-add-repository ppa:ansible/ansible apt-get upd ...
- oracle 根据出生日期计算年龄的年月日
select years,months,abs( trunc( newer_date- add_months( older_date,years*12+months ) ) ) days from ( ...
- C++单元测试gtest【搬砖】
https://www.cnblogs.com/fnlingnzb-learner/p/6927834.html
- ES6 常用总结(前端开发js技术进阶提升总结)
一.变量声明const和let 在ES6之前,我们都是用var关键字声明变量.无论声明在何处,都会被视为声明在函数的最顶部(不在函数的最顶部就在全局作用域的最顶部).这就是函数变量提升例如: 不用关心 ...
- Windows下命令行怎样登录MySQL
直接cmd回车然后 “ mysql -u root -p ” 登录时出现错误,原来是权限不够 打开cmd时需要以管理员的身份打开 然后继续使用 “ mysql -u root -p ” 还是不行, ...