栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

使用类的__new__方法作为工厂:__init__被调用两次

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用类的__new__方法作为工厂:__init__被调用两次

当构造一个对象时,Python会调用其

__new__
方法来创建该对象,然后
__init__
在返回的对象上进行调用。当您
__new__
通过调用从内部创建对象时
Triangle()
,将导致对
__new__
和的进一步调用
__init__

您应该做的是:

class Shape(object):    def __new__(cls, desc):        if cls is Shape: if desc == 'big':   return super(Shape, cls).__new__(Rectangle) if desc == 'small': return super(Shape, cls).__new__(Triangle)        else: return super(Shape, cls).__new__(cls, desc)

它会创建一个

Rectangle
Triangle
不触发调用
__init__
,然后
__init__
仅被调用一次。

编辑以回答@Adrian关于super如何工作的问题:

super(Shape,cls)
搜索
cls.__mro__
以查找
Shape
,然后向下搜索序列的其余部分以找到属性。

Triangle.__mro__
(Triangle, Shape, object)

Rectangle.__mro__
(Rectangle, Shape, object)
Shape.__mro__
而是正义
(Shape,object)
。对于任何一种情况,当您调用
super(Shape,cls)
它时,它都会忽略mro序列中的所有内容,
Shape
因此只剩下单个元素元组
(object,)
,它用于查找所需的属性。

如果您拥有钻石继承关系,这将变得更加复杂:

class A(object): passclass B(A): passclass C(A): passclass D(B,C): pass

现在B中的方法可能会使用

super(B, cls)
,如果是B的实例会搜索,
(A,object)
但是如果你有一个
D
实例,相同的调用
B
将搜索,
(C, A, object)
因为
D.__mro__
is是
(B, C, A,object)

因此,在这种特殊情况下,您可以定义一个新的mixin类,该类可以修改形状的构造行为,并且可以具有从现有的三角形和矩形继承但构造不同的专用三角形和矩形。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/639412.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号