以下代码是基本Angle对象的初始化方法,其中float为其父类。
class Angle(float):
def __init__(self, value, vertex2 = None, vertex3 = None, atype = 'convex'):
#type-checking for the input args
try:
#checks for value arg
angle = value
if not (0 < value < 360):
angle %= 360
except TypeError:
#checks for three-vertice args
try:
angle = three_point_angle(value, vertex2, vertex3)
#three_point_angle is a function to calculate the
#convex angle between three vertices (i.e. at vertex2)
if atype == 'concave':
angle = 360 - angle
self._vdict = {}
for pos, vert in enumerate([value, vertex2, vertex3]):
self._vdict[pos] = vert
except:
raise TypeError(\
"You may only specify either an angle value, or three vertices from which \
to calculate the angle. You input a %s, %s and %s value." % (\
type(value), type(vertex2), type(vertex3)))
self.angle = angle
这个类背后的想法是你可以输入角度值,或指定三个顶点(和一个可选的角度类型参数)来自动计算角度。最后,self.angle总是被初始化,这就是所有算术发生的地方(因此__add__(self, other)
会影响self.angle
)。
它继承自float
的原因是继承其反射和增强赋值的魔术方法,这些方法都在self.angle
上执行。
当试图为顶点输入三个值时出现问题。由于它继承自float
,因此不能使用多个参数,因此会引发错误。我该如何解决这个问题?我的猜测是我必须为__new__
创建一个Angle
方法,以便调用它而不是超类',但我不知道我在哪里开始甚至是如果这是解决这个问题的正确/最佳方式。
答案 0 :(得分:1)
请参阅此相关问题:
How to overload `float()` for a custom class in Python?
然后改变
class Angle(float):
到
class Angle(object):
答案 1 :(得分:1)
您不需要从float继承。你认为在self.angle上执行魔术方法是错误的;他们只是在自我身上表演。请尝试以下代码:
class Angle(float):
def __init__(self, x):
self.angle = x
def double(self):
self.angle *= 2
a = Angle(1)
a.double()
print a # prints 1.0
print a.angle # prints 2
a *= 5
print a # prints 5.0
print a.angle # throws AttributeError
a.angle
不受魔术方法的影响,float(a)
也不受a.angle
上的操作影响。 float
是不可变的,因此a *= 5
创建了一个具有不同属性的新浮点数。
因此,如果您将Angle
更改为继承自Object
而不是float
,则可以控制初始化,而不会丢失任何便利。