python:__new__和__init__

python:__new__和__init__

1 前言

在Python中,每个对象都有两个特殊的方法:__new__和__init__。这两个方法在对象的创建和初始化过程中起着重要的作用,但它们的功能和用法有所不同。

1.1 功能上的区别

__new__方法是Python中的一个魔术方法(Magic Method),用于创建一个新的对象实例。当我们在Python中创建一个对象时,实际上是调用了__new__方法来创建一个新的对象实例,然后再调用__init__方法来初始化这个对象。

__init__方法是Python中的一个普通方法,用于初始化一个已经存在的对象。当我们使用__new__方法创建一个新的对象实例后(不可为None),就会调用这个对象的__init__方法来对对象进行初始化。

1.2 参数上的区别

__new__方法通常需要三个参数:第一个参数是类(cls,即class),第二个参数是传入的参数列表(args),即位置参数;第三个参数也是传入的参数列表(kwargs),即关键字参数。__new__方法的返回值是一个新的对象实例。

__init__方法通常需要1个或以上参数:第一个参数是对象实例(self,也就是__new__方法返回的对象实例),后续可有可无的若干参数是传入的参数列表(args),常用于设置实例化对象属性。__init__方法的返回值是None。

1.3 调用时机上的区别

__new__方法在创建对象时被调用,它的调用时机是在__init__方法之前。__new__方法的返回值是一个新的对象实例,这个实例会被传递给__init__方法进行初始化。

__init__方法在对象被创建后被调用,它的调用时机是在__new__方法之后。__init__方法用于对已经存在的对象进行初始化,它的参数列表通常包括传递给类的构造函数的参数。

上述可知,没有__new__方法,我们就无法创建新的对象实例;没有__init__方法,我们就无法对已经存在的对象进行初始化。两者功能上虽有差别,但是是用于共同来创建和初始化一个对象的,所以两者均很重要,下面则是具体使用的分析。

2 使用

2.1 简单示例

class Clazz:

    def __new__(cls, *args, **kwargs):
        print("调用__new__")
        print(f'cls:{
     
     cls}, args:{
     
     args}, kwargs: {
     
     kwargs}')

    def __init__(self, name):
        print("调用__init__")
        print(f'self:{
     
     self}, name:{
     
     name}')
        self.name = name


clazz = Clazz("xiaoxu")

执行结果:

调用__new__
cls:<class '__main__.Clazz'>, args:('xiaoxu',), kwargs: {
   
   }

可以看到,上述代码先执行了__new__,但是并未执行__init__方法,因为只有当我们使用__new__方法创建一个新的对象实例后,才会调用这个对象的__init__方法来对对象进行初始化。

__new__是一个内置staticmethod,其首个参数必须是type类型,即要实例化的class本身,其负责为传入的class type分配内存、创建一个新实例并返回该实例,该返回值其实就是后续执行__init__函数的入参self。

参考Python的源码typeobject.c中定义的type_call函数:

static PyObject *
 type_call(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
   
   
     PyObject *obj;
 
    if (type->tp_new == NULL) {
   
   
         PyErr_Format(PyExc_TypeError,
                     "cannot create '%.100s' instances",
                      type->tp_name);
        return NULL;
     }
 ...
    obj = type->tp_new(type, args
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值