我想为复杂类型创建一个新的__str__
方法。
import numpy as np
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))
a = Phasor(1+1j)
print(a)
print(type(a))
print(a**2)
print(type(a**2))
返回
1.41 ∠ 45.0°
<class '__main__.Phasor'>
2j
<type 'complex'>
在这种情况下,将实例提升为幂将返回复杂类型的实例,而不是子类实例。
我希望继承的方法返回子类的新实例并且不复杂。
答案 0 :(得分:2)
为了使算术运算符返回子类的实例,您必须实现相关的special methods,例如__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°