我有点被困在这里。我基本上是在试验阶段,我想知道我是否可以将int
子类化,以便它将与您的旧int
完全一样,除了您将能够分配一个“未知”值,在算术运算的情况下,将作为1。
所以我可以说:
>>> uint(5) + 5
10
>>> uint('unknown')
unknown
>>> int(uint('unknown'))
1
>>> uint('unknown') + 5
6
>>>
事实上,它与float('inf')
已经有的相似,只是我只需要整数加上单个“特殊”值。
我想象的工作方式是:
class uint(int):
def __init__(self, value):
self.value = value
self.unknown = self.value == "unknown"
def __int__(self):
return 1 if self.unknown else self.value
def __str__(self):
return "unknown" if self.unknown else str(self.value)
但是当我尝试将其ValueError: invalid literal for int() with base 10: 'unknown'
实例化时,此示例会抛出uint('unknown')
。
这可能吗?我该怎么做呢?
背景等级1
如果有人问,背景是我有一个可迭代的列表,我想用itertools.product
创建一个新的。但之前,我想利用__len__
,以防一些迭代器实现它,以便能够猜测(最小)最终元素的数量。所以就最终数字而言,对于那些没有__len__
的迭代,我假设为1.
我想用class uint(int)
执行此操作的原因是我希望能够安全地公开单独的计数(以便有人可以按下以下内容:“loading(1500 = 10 * 10 * unknown) * 15)元素“仍然传递其中一些”未知“的信息。
背景等级2
我实际上是想象一种情况,当一个库提供这个类用于定义可迭代对象'__len__
时,它们可以返回一个基于“最小”,“最大”的数字或“最好的猜测”,但仍然没有被它在一些简单的数学中的进一步使用所困扰。
>>> count = uint(100, 'minimum')
>>> print count
"minimum of 100"
>>> count * 20
2000
>>>
想象一个带有迭代器的对象,它读取一个巨大的文件:为什么对象不能说“好,文件是400 MiB,所以至少有4,000条记录”?
所以一个额外的问题:什么更简单:继承int或创建一个新类,但必须实现和维护aritmethic操作的接口?
答案 0 :(得分:3)
我认为存在一些概念问题会超过您的实施问题。
将“未知值”视为1使得它们并非真正未知。为了对浮点数进行类比,有一个定义良好的"Not a Number",它将参与数学运算,但在大多数情况下会产生NaN。例如:
>>> f = float('NaN')
>>> 42 * f
nan
这是一件好事,因为NaN确实不是一个数字所以使用它的算术不应该产生看似有效的结果。如果您按照建议实现了“未知整数”,则未知值将产生无意义的结果。例如:
>>> u = uint('unknown')
>>> 42 * u
42
你得到一个正确的整数,但这真的是你想要的语义吗?另一个类似的情况是除以零,这是数学上未定义的。任何可能被克隆到位的价值都会产生数学上的荒谬。由于(x/y) * y == x
(当且仅当y != 0
)您可能期望:
>>> (42 / 0) * 0 # this doesn't really work
42
但如果不打破数学,你就无法做到这一点。
答案 1 :(得分:2)
不完全确定您为什么要这样做,但以下情况应该有效:
class uint(int):
def __new__(cls, value):
unknown = value == 'unknown'
obj = super(uint, cls).__new__(cls, 1 if unknown else value)
obj.unknown = unknown
return obj
def __str__(self):
return 'unknown' if self.unknown else super(uint, self).__str__()
这里的想法是,不是将int值存储在名为self.value
的属性中,而是使用您要使用的值来执行超类的实例化。
答案 2 :(得分:2)
您可以使用None
作为尚未分配的值的占位符。例如:
>>> a = [4, 3, 1, 5, 2, None, None]
>>> len(a)
7
>> a*3
[4, 3, 1, 5, 2, None, None, 4, 3, 1, 5, 2, None, None, 4, 3, 1, 5, 2, None, None]