Чтобы арифметические операторы возвращали экземпляр вашего подкласса, вам необходимо реализовать соответствующие специальные методы , такие как __add__
, __mul__
, __pow__
и т. Д.
Плохая новость в том, что таких методов много. Хорошей новостью является то, что вы можете написать код, который автоматически генерирует эти функции для вас. Вот декоратор класса, который делает именно это:
def add_arithmetic_methods(cls):
def make_func(func_name):
def func(self, *args, **kwargs):
super_method = getattr(super(cls, self), func_name)
return type(self)(super_method(*args, **kwargs))
func.__name__ = func_name
func.__qualname__ = '{}.{}'.format(cls.__qualname__, func_name)
func.__module__ = cls.__module__
return func
for func_name in ['add', 'sub', 'mul', 'matmul', 'truediv', 'floordiv',
'mod', 'divmod', 'pow', 'lshift', 'rshift', 'and',
'xor', 'or', 'radd', 'rsub', 'rmul', 'rmatmul',
'rtruediv', 'rfloordiv', 'rmod', 'rdivmod', 'rpow',
'rlshift', 'rrshift', 'rand', 'rxor', 'ror', 'iadd',
'isub', 'imul', 'imatmul', 'itruediv', 'ifloordiv',
'imod', 'ipow', 'ilshift', 'irshift', 'iand', 'ixor',
'ior', 'neg', 'pos', 'abs', 'invert']:
func_name = '__{}__'.format(func_name)
func = make_func(func_name)
setattr(cls, func_name, func)
return cls
Наденьте это на Phasor
класс, и все готово:
@add_arithmetic_methods
class Phasor(complex):
def __str__(self):
magnitude = (self.real**2 + self.imag**2)**.5
angle = np.arctan2(self.imag, self.real)
return "%s ∠ %s°" % (round(magnitude, 2), round(np.degrees(angle), 2))
c = Phasor(3+5j)
print(c**2)
# output: 34.0 ∠ 118.07°