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

Subclassing int - unexpected behaviour with range

我们尝试创建一个可变 int,它从其他地方引用它的值。它 似乎 在大多数情况下表现良好,但是,当将它传递给范围时,我们会得到意想不到的结果。

subclass 包含一堆样板,因此我将包括我知道的方法,这些方法被范围调用以推断将重现行为的 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 创建一个 0 - 4 列表。

range 在查找其值时是否假设 'value' 在 int 类型 class 上的存储位置?在 Python 中制作透明参考类型框的最佳方法是什么?

谢谢

您在 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(5).

初始化 IntRef

不要子class int然后覆盖所有方法。如果你这样做,base class 会认为你有一个值,而 subclass 会认为你有不同的值。相反,subclass numbers.Integral 并实现所有抽象方法。那么您可以确定您的实施是唯一的游戏。