继承`int`的类会像变量赋值一样变得奇怪

时间:2016-06-11 21:56:26

标签: python class python-3.x inheritance

由于缺乏更好的头衔,这是我到目前为止所得到的。

class cordinate(int):
    def __new__(self, *args, **kwargs):
        self.x = args[0]
        self.y = args[1]

        ## Try to get pixel [0,0] and see what it got:
        if self.x == 0 and self.y == 0:
            print('New Here')
            print(self.x, self.y, self.angle, self.distance_from_edge)

        self.angle = 225
        self.distance_from_edge = 13

        args = [self.distance_from_edge,]
        return super(cordinate, self).__new__(self, *args, **kwargs)

cordinates = [cordinate(0,0), cordinate(2,10), cordinate(3,8)]

正如预期的那样,此代码会抛出错误:

New Here
Traceback (most recent call last):
  File "test.py", line 17, in <module>
    cordinates = [cordinate(0,0), cordinate(2,10), cordinate(3,8)]
  File "test.py", line 9, in __new__
    print(self.x, self.y, self.angle, self.distance_from_edge)
AttributeError: type object 'cordinate' has no attribute 'angle'

无论出于何种原因,我尝试了以下方法:

if self.x == 2 and self.y == 10:

此代码将输出:

New Here
2 10 225 13

现在,我确信对此有一个简单的解释,并且不需要恐慌或开始相信鬼魂。

但是我已经玩过但却无法理解它。这个行为的解释是什么 - 它有名字吗?为什么新创建的实例可以有一个值,该值将被设置为2行?

期望值:始终崩溃 - 因为我故意在顶部放置一个带有未定义键的打印件。
Python: 3.5.1(Windows 8)

1 个答案:

答案 0 :(得分:3)

the data model documentation可以看出,__new__的第一个参数是类(通常为cls),而不是实例(通常为self)。因此,您要在cordinate类上设置类属性(请注意,这是一个错字,类名应该是CamelCased)而不是每个实例。只要对__new__第一次调用成功,就会在类中为所有后续调用设置这些属性。

如果要在__new__中设置实例属性,请在拥有实例后执行,例如:

class Coordinate(int):

    def __new__(cls, *args, **kwargs):
        self = super(Coordinate, cls).__new__(cls, *args[2:], **kwargs)
      # ^ or 'inst' or whatever you like
        self.x, self.y = args[:2]
        ...
        return self