- 前言
- 一、__init__()方法和__new__()方法是什么?
- 二、__init__()方法和__new__()方法的使用?
在阅读流畅的python时,第一章中出现的特殊方法,注意到__init__()方法和__new__()方法,百度查了一下觉得稍微有一点晦涩,所以大概理了一下。
一、init()方法和__new__()方法是什么?这里先参照一下官方文档。
object.new(cls[, …])
调用以创建一个 cls 类的新实例。new() 是一个静态方法 (因为是特例所以你不需要显式地声明),它会将所请求实例所属的类作为第一个参数。其余的参数会被传递给对象构造器表达式
(对类的调用)。new() 的返回值应为新对象实例 (通常是 cls 的实例)。典型的实现会附带适宜的参数使用 super().new(cls[, …]),通过超类的 new()
方法来创建一个类的新实例,然后根据需要修改新创建的实例再将其返回。 如果 new() 未返回一个 cls 的实例,则新实例的 init() 方法就不会被执行。
new() 的目的主要是允许不可变类型的子类 (例如 int, str 或 tuple) 定制实例创建过程。它也常会在自定义元类中被重载以便定制类创建过程。object.init(self[, …]):
在实例 (通过 new()) 被创建之后,返回调用者之前调用。其参数与传递给类构造器表达式的参数相同。一个基类如果有 init() 方法,则其所派生的类如果也有
init() 方法,就必须显式地调用它以确保实例基类部分的正确初始化;例如: super().init([args…]).
上述是对方法的描述,简而言之__new__()方法和__init__()都是用于创建实例。
按我的理解来讲,我们知道,创建类后,方法__init__()在实例化后会自动调用,例如
class Person(object):
def __init__(self, name, age):
print("in __init__")
self.name = name
self.age = age
p = Person("Wang", 33)
实例化会自动将调用Person的__init__().但在此之前其实还有一个步骤,那就是调用__new___()方法。_init_()方法有一个参数self,只知道写这个方法时必须要写self,虽然可以不叫这个名字,可以叫this等其它巴拉巴拉的(建议是self),但是必须写。可这个参数传入什么?其实传入的就是__new__()方法return的值。
通俗的讲:
相当于,我要先有一个人,然后在这个人的基础上进行添加属性,叫什么名字,多大了,有多高,电话是多少。这就是实例化的两个步骤,也是两个方法的作用:先new一个人,再把这个人用self传到init的工厂进行包装,加名字,加年龄(self.name=name.self.age=age,这个人的名字是name,这个人的年龄是age,理解了这个也就很好理解init方法的原理)
上述是我浅显的见解,_new_()里面怎么写还需要研究一下,文档说是静态方法啊,参数要是cls啊。return要用super()通过超类的new方法创建实例。
二、init()方法和__new__()方法的使用?init()方法不过多赘述,学习类的时候应该都有学习到。
new()方法作为新式类中的静态方法,默认调用该父类的__new__()方法构造实例,如果父类也没有重写该方法就一直调用到object类。
其次该方法同其它静态方法不同,不需要使用修饰器@staticmethod。
class Person():
def __new__(cls, *args, **kwargs):
return super(Person, self).__new__()#用super方法自动调用父类方法
p=Person
参数cls是当前要实例化的类。当然这个也可以是其他类,如果return返回的不是当前类的实例,那么后续的__init__()方法就不会被正确调用,因为return的值应该是当前类的实例对象传给self。
至于中间加什么就随便,一定要确保返回值正确。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)