繁体   English   中英

允许子类在python中从其父类中获得不同的* args和** kwargs

[英]Allowing a subclass to have different *args and **kwargs from its parent class in python

以下代码是基本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.angleself.angle

当人们试图为顶点输入三个值时会出现问题。 由于它继承自float ,因此不能使用多个参数,因此会引发错误。 我该如何解决这个问题? 我的猜测是我必须为Angle创建一个__new__方法,以便调用它而不是超类',但我不知道我从哪里开始,或者即使它是正确的/最好的方式走吧。

看到这个相关的问题:

如何在Python中为自定义类重载`float()`?

然后改变

class Angle(float):

class Angle(object):

您不需要从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 s是不可变的,所以a *= 5创建了一个具有不同属性的新float。

因此,如果将Angle更改为继承自Object而不是float ,则可以控制初始化,而不会丢失任何便利。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM