子类化int - 带范围的意外行为

时间:2017-07-31 12:10:53

标签: python-3.x reference int subclassing

我们尝试创建一个可变的int,它从其他地方引用它的值。在大多数情况下,它出现,但是,当它处理到范围时,我们会得到意想不到的结果。

子类包含一堆样板文件,因此我将包含我知道的范围调用的方法,以推断将重现行为的int值。

class IntRef(int):

    def __init__(self, *args, **kwargs):
        self.reference = 5
        super().__init__()

    def __le__(self, other):
        return self.reference.__le__(other)

    def __sub__(self, other):
        return self.reference.__sub__(other)

    ...

这种行为:

a = IntRef()
list(range(a)) # [] not [0, 1, 2, 3, 4]

我相信我们已经实现了与int相关的所有Dunder方法,所以我希望range创建一个零-4列表。

范围是否假设'值'在找到它的值时存储在int类型中?在Python中制作透明引用类型框的最佳方法是什么?

由于

2 个答案:

答案 0 :(得分:0)

您在IntRef.__new__中没有做任何不同的事情,因此通过致电IntRef()并使用int.__new__,您会获得0的值。

定义合适的IntRef.__new__

class IntRef(int):

    def __new__(cls, reference=5, *args, **kwargs):
        return super().__new__(cls, reference, *args, **kwargs)

你会得到想要的结果:

a = IntRef()
list(range(a))
Out[78]: [0, 1, 2, 3, 4]

但是使用一个论点似乎很奇怪而且令人困惑;我只是坚持使用默认的int行为,并使用IntRef初始化IntRef(5)

答案 1 :(得分:-1)

不要继承int,然后覆盖所有方法。如果你这样做,基类会认为你有一个值,子类会认为你有不同的值。相反,子类numbers.Integral并实现所有抽象方法。然后你可以确定你的实施是镇上唯一的游戏。