加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – 如何设置__new__返回的值类而不使用super?

发布时间:2020-12-20 13:45:10 所属栏目:Python 来源:网络整理
导读:我希望B成为某个A类的子类,我想要覆盖A .__ new__1.通常,我的代码将具有以下基本结构: class B(A): def __new__(cls,...): ret = super(B,cls).__new__(cls,...) # modify ret as needed return ret # type(ret) is cls # ... 这样,类型(B(…))确实是B.(注
我希望B成为某个A类的子类,我想要覆盖A .__ new__1.通常,我的代码将具有以下基本结构:

class B(A):
    def __new__(cls,...):
        ret = super(B,cls).__new__(cls,...)

        # modify ret as needed

        return ret  # type(ret) is cls

    # ...

这样,类型(B(…))确实是B.(注意:super(B,cls).__ new __(cls,…)中的省略号不需要表示与省略号表示的项目相同的项目在B .__ new __的签名.)

但是现在假设我想使用一些工厂方法/函数A_Factory(它返回一个A类型的对象)返回的值作为构造函数中变量ret的起始值.如果我只是编码这个:

class B(A):
    def __new__(cls,...):
        ret = A_Factory(...)

        # modify ret as needed

        return ret  # type(ret) is A

…然后输入(B(…))将是A,而不是B.

在上面的B .__ new__的第二个版本中设置ret类的正确方法是什么,类型(B(…))是B,更一般地说,对于B的任何直接或间接子类C,类型(C(…))是C?

1我知道通常不需要覆盖父类的__new__,但在这里我对需要的不常见情况感兴趣.

解决方法

您可以将实例的 __class__属性设置为传递给__new__的cls:

class A(object):
    def __init__(self):
        self.x = 2

def A_Factory():
    return A() 

class B(A):
    def __new__(cls):
        ret = A_Factory()

        ret.__class__ = cls  # Override the class.

        return ret  # type(ret) is cls

class C(B):
    pass


if __name__ == "__main__":
    b = B() 
    print(b.x)
    print(type(b))
    print(isinstance(b,B)) 
    print(isinstance(b,A))
    c = C()
    print(type(C))

输出:

2
<class '__main__.B'>
True
True
<class '__main__.C'>

但是,这有一些限制. commit that added the ability to assign to __class__列出了它们:

Make __class__ assignment possible,when the object structures are the
same. I hope the test for structural equivalence is stringent enough.
It only allows the assignment if the old and new types:

  • have the same basic size
  • have the same item size
  • have the same dict offset
  • have the same weaklist offset
  • have the same GC flag bit
  • have a common base that is the same except for maybe the dict and weaklist (which may have been added separately at the same offsets
    in both types)

如果你在任一类上定义了它们,它们也需要具有相同的__slots__.实际上,这通常意味着两个类都需要在Python中实现.尝试使用常规Python类和int或tuple或其他在C中实现的东西不太可行.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读