博客
关于我
第8.6节 Python类中的__new__方法深入剖析:调用父类__new__方法参数的困惑
阅读量:113 次
发布时间:2019-02-25

本文共 2280 字,大约阅读时间需要 7 分钟。

探索Python类的__new__方法参数传递原则

在Python的对象创建机制中,__new__方法扮演着"工厂"角色,它负责创建对象实例。对于开发者而言,理解__new__方法的工作机制至关重要,尤其是在处理类实例化时的参数传递问题。本文将通过实际案例,深入探讨__new__方法的参数传递规则。

案例1:调用object类的__new__方法传参验证

在Python中,object类是所有类的基础类,它的__new__方法定义如下:

def __new__(*args, **kwargs)

从表面看,似乎可以传递多个参数,但实际情况却并非如此。我们可以通过以下实验来验证这一点。

实验1:传递全部参数

class Cir:    def __new__(cls, *args, **kwargs):        print("Python传递给__new__的参数:")        print(f"***cls: {cls}")        print(f"***args: {args}")        print(f"***kwargs: {kwargs}")        inst = super().__new__(cls, *args, **kwargs)        print("__new__返回值:", inst)        return inst    def __init__(self, radius):        print("In init, self的值为:", self, ", radius的值为:", radius)        self.radius = radius

实验结果

cir = Cir(10)# 报错:TypeError: object.__new__() takes no arguments

分析

通过上述实验可以看到,当我们尝试传递额外的参数给__new__方法时,会抛出TypeError错误,提示object.new()不接受任何参数。这表明,尽管object.__new__的函数签名允许传递参数,但实际执行时,只能传递类参数cls。

案例2:调用自定义父类的__new__方法传参验证

为了更全面地理解__new__方法的参数传递规则,我们可以构建一个类继承体系,探索不同情况下的参数传递行为。

类定义

class Vehicle:    passclass Car(Vehicle):    def __new__(cls, *args, **kwargs):        print(f"Car.__new__被调用,参数为: {args}, {kwargs}")        return super().__new__(cls, *args, **kwargs)    def __init__(self, radius):        self.radius = radius

实验1:Vehicle类未重写__new__

cir = Car(10)

实验结果

TypeError: Car.__new__() missing 1 required positional argument: 'radius'

实验2:Vehicle类未重写__new__

class Vehicle:    passclass Car(Vehicle):    def __new__(cls, *args, **kwargs):        print(f"Car.__new__被调用,参数为: {args}, {kwargs}")        return super().__new__(cls, *args, **kwargs)    def __init__(self, radius):        self.radius = radiuscir = Car(10)

实验结果

TypeError: Car.__new__() missing 1 required positional argument: 'radius'

实验3:Vehicle类未重写__new__

class Vehicle:    passclass Car(Vehicle):    def __new__(cls, *args, **kwargs):        print(f"Car.__new__被调用,参数为: {args}, {kwargs}")        return super().__new__(cls, *args, **kwargs)    def __init__(self, radius):        self.radius = radiuscir = Car(10)

实验结果

TypeError: Car.__new__() missing 1 required positional argument: 'radius'

结论

通过上述实验可以得出以下结论:

  • 调用object.new()时,只能传递cls参数,其他参数会被忽略。
  • 在自定义类的__new__方法中,可以传递所有参数给父类的__new__方法执行。
  • 如果父类没有重写__new__方法,则只能传递cls参数;否则,传递所有参数。
  • 在实际开发中,理解__new__方法的参数传递规则可以帮助我们更好地控制对象的创建过程,特别是在需要定制对象创建逻辑时。

    转载地址:http://cfi.baihongyu.com/

    你可能感兴趣的文章
    Objective-C实现十进制转N进制算法(附完整源码)
    查看>>
    Objective-C实现十进制转八进制算法(附完整源码)
    查看>>
    Objective-C实现华氏温度转摄氏温度(附完整源码)
    查看>>
    Objective-C实现单例模式(附完整源码)
    查看>>
    Objective-C实现单向链表的反转(附完整源码)
    查看>>
    Objective-C实现单向链表的反转(附完整源码)
    查看>>
    Objective-C实现单字母密码算法(附完整源码)
    查看>>
    Objective-C实现单循环链表算法(附完整源码)
    查看>>
    Objective-C实现单词计数(附完整源码)
    查看>>
    Objective-C实现单链表反转(附完整源码)
    查看>>
    Objective-C实现博福特密码算法(附完整源码)
    查看>>
    Objective-C实现卡尔曼滤波(附完整源码)
    查看>>
    Objective-C实现卡尔曼滤波(附完整源码)
    查看>>
    Objective-C实现卡尔曼滤波(附完整源码)
    查看>>
    Objective-C实现卷积(附完整源码)
    查看>>
    Objective-C实现压缩文件夹(附完整源码)
    查看>>
    Objective-C实现原型模式(附完整源码)
    查看>>
    Objective-C实现双向A*算法(附完整源码)
    查看>>
    Objective-C实现双向广度优先搜索算法(附完整源码)
    查看>>
    Objective-C实现双向循环链表(附完整源码)
    查看>>