Python多重继承:调用哪个__new__?

发布于 2024-08-19 00:16:26 字数 1711 浏览 9 评论 0原文

我有一个类Parent。我想为 Parent 定义一个 __new__ ,以便它在实例化时发挥一些作用(为什么,请参阅脚注)。我还希望子类继承这个类和其他类以获得父类的功能。 Parent__new__ 将返回子类基类和 Parent 类的子类的实例。

这就是子类的定义方式:

class Child(Parent, list):
    pass

但现在我不知道在 Parent__new__ 中调用什么 __new__。如果我调用 object.__new__,上面的 Child 示例会抱怨应该调用 list.__new__。但是Parent怎么知道呢?我让它工作,所以它循环遍历所有 __bases__,并在 try: 块内调用每个 __new__

class Parent(object):
    def __new__(cls, *args, **kwargs):
        # There is a special wrapper function for instantiating instances of children
        # classes that passes in a 'bases' argument, which is the __bases__ of the
        # Children class.
        bases = kwargs.get('bases')
        if bases:
            cls = type('name', bases + (cls,), kwargs.get('attr', {}))
            for base in cls.__mro__:
                if base not in (cls, MyMainType):
                    try:
                        obj = base.__new__(cls)
                        break
                    except TypeError:
                        pass
            return obj
        return object.__new__(cls)

但这看起来像是一个 hack 。当然,必须有更好的方法来做到这一点?

谢谢。

  • 我想使用 __new__ 的原因是这样我可以返回一个子类的对象,该对象具有分配给该类的一些动态属性(神奇的 __int__ 属性等)。我可以在__init__中完成此操作,但如果新类具有不同的内部结构,我将无法在 __init__ 中修改 self.__class__ ,情况就是这样这里由于多重继承。

I have a class Parent. I want to define a __new__ for Parent so it does some magic upon instantiation (for why, see footnote). I also want children classes to inherit from this and other classes to get Parent's features. The Parent's __new__ would return an instance of a subclass of the child class's bases and the Parent class.

This is how the child class would be defined:

class Child(Parent, list):
    pass

But now I don't know what __new__ to call in Parent's __new__. If I call object.__new__, the above Child example complains that list.__new__ should be called. But how would Parent know that? I made it work so it loops through all the __bases__, and call each __new__ inside a try: block:

class Parent(object):
    def __new__(cls, *args, **kwargs):
        # There is a special wrapper function for instantiating instances of children
        # classes that passes in a 'bases' argument, which is the __bases__ of the
        # Children class.
        bases = kwargs.get('bases')
        if bases:
            cls = type('name', bases + (cls,), kwargs.get('attr', {}))
            for base in cls.__mro__:
                if base not in (cls, MyMainType):
                    try:
                        obj = base.__new__(cls)
                        break
                    except TypeError:
                        pass
            return obj
        return object.__new__(cls)

But this just looks like a hack. Surely, there must be a better way of doing this?

Thanks.

  • The reason I want to use __new__ is so I can return an object of a subclass that has some dynamic attributes (the magic __int__ attributes, etc) assigned to the class. I could have done this in __init__, but I would not be able to modify self.__class__ in __init__ if the new class has a different internal structure, which is the case here due to multiple inheritance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

属性 2024-08-26 00:16:26

我认为这会给你带来你想要的:

return super(Parent, cls).__new__(cls, *args, **kwargs)

并且你不需要 bases 关键字参数。除非我误会你的意思并且你是故意把它放在那里的。

I think this will get you what you want:

return super(Parent, cls).__new__(cls, *args, **kwargs)

and you won't need the bases keyword argument. Unless I'm getting you wrong and you're putting that in there on purpose.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文