【问题标题】:Allowing a subclass to have different *args and **kwargs from its parent class in python允许子类在 python 中与其父类具有不同的 *args 和 **kwargs
【发布时间】:2014-01-07 22:30:07
【问题描述】:

以下代码是以float为父类的基本Angle对象的初始化方法。

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,因此它不能接受多个参数,因此会引发错误。我将如何解决这个问题?我的猜测是我必须为Angle 创建一个__new__ 方法,以便调用它而不是超类',但我不知道我什至从哪里开始,或者即使它是正确的/解决这个问题的最佳方法。

【问题讨论】:

  • 什么是完整的错误回溯?我认为问题不是您所描述的。
  • a = Angle(Vertex(0, 0), Vertex(0, 10), Vertex(10, 10)) 导致TypeError: float() takes at most 1 argument (3 given)

标签: python class inheritance


【解决方案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 上的操作的影响。 floats 是不可变的,所以 a *= 5 创建了一个新的浮点数,具有不同的属性。

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

【讨论】:

    【解决方案2】:

    查看这个相关问题:

    How to overload `float()` for a custom class in Python?

    然后改变

    class Angle(float):
    

    class Angle(object):
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-16
      • 1970-01-01
      • 2020-09-16
      • 2017-01-28
      • 1970-01-01
      • 2016-08-30
      • 1970-01-01
      • 2018-10-13
      相关资源
      最近更新 更多