是否可以在Python元类中重写运算符(如__add __ ??

问题描述 投票:0回答:2

在我的用例中,如果可以实现类的添加,而不是它们的对象的添加,那将很好。 Python可能吗?我的IDE将__add__显示为type的方法。如何正确覆盖它?

否则,我正在考虑遵循可怕的forbidden way of doing things,也许是猴子补丁type

class MyClass:
    def __add__(self, other):
        return "some funny result"


# Works fine!
MyClass() + MyClass()


class MyClassOperand(type):
    def __new__(cls, *args, **kwargs):
        """Here, there will be things to instantiate the real MyClass ..."""
        # return object.__new__(cls)

    def __add__(self, other):
        return "some funny result"


# TypeError: unsupported operand type(s) for +: 'type' and 'type'
MyClassOperand + MyClassOperand
python python-3.x operator-overloading metaclass
2个回答
1
投票

基于this answer,这是我的操作方式:

class MyMetaClass(type):

    def __add__(self, other):
        return "some META funny result"


class MyClass(metaclass=MyMetaClass):
    def __add__(self, other):
        return "some funny result"


# Works fine: "some funny result"
print(MyClass() + MyClass())

# Works fine: "some META funny result"
print(MyClass + MyClass)

0
投票

有效-一个更实用的示例是简单的元类,它将创建两个添加的类的新组成子类。前提是班级工作通过使用super()调用,它可以毫无问题地工作:

class Addable(type):
    def __add__(cls, other_cls):  # All metaclass methods receive classes as their "self" parameters
                                  # so they are effectively "class methods" for those
        meta = type(cls)  # this should be "Addable" itself, or a composed subclass of it
        new_cls = meta(
            f"Composed{cls.__name__}{other_cls.__name__}",
            (cls, other_cls),  # base classes
            {}, # empty namespace
        )
        return new_cls


# Example:


class Base(metaclass=Addable):
    pass

class Cls1(Base):
    def __init__(self, *args, **kwargs):
        self.parameter1 = kwargs.pop("parameter1", None)
        super().__init__(*args, **kwargs)

    def m1(self):
        print("method 1")

class Cls2(Base):
    def __init__(self, *args, **kwargs):
        self.parameter2 = kwargs.pop("parameter2", None)
        super().__init__(*args, **kwargs)

    def m2(self):
        print("method 2")

Cls3 = Cls1 + Cls2

并将其粘贴到终端上:


In [8]: Cls3().m2()                                                                              
method 2

In [9]: Cls3(parameter1 = "bla").parameter1                                                      
Out[9]: 'bla'

© www.soinside.com 2019 - 2024. All rights reserved.