在我的用例中,如果可以实现类的添加,而不是它们的对象的添加,那将很好。 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
基于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)
有效-一个更实用的示例是简单的元类,它将创建两个添加的类的新组成子类。前提是班级工作通过使用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'