子类化 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
并实现所有抽象方法。那么您可以确定您的实施是唯一的游戏。
我们尝试创建一个可变 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
并实现所有抽象方法。那么您可以确定您的实施是唯一的游戏。