shx*_*hx2 7 python int inheritance properties operators
我有一个值,通常在我的代码中以不同的单位使用.例如,以BYTES的数量表示缓冲区大小,但在许多地方将大小称为KB或MB(这只是一个示例,而不是我的实际用例).
为了优雅和易用,我想避免显式转换(例如size/1024,或b_to_mb(size)),因为它们在许多不同的地方都需要.
我认为我可以通过属性实现这一点,这使得转换变得容易(x.kb或x.mb),并且还使调用者不知道存储的实际值的单位.
我的代码看起来像这样:
class BufferSize(int):
@property
def b(self):
return int(self)
@property
def kb(self):
return self.b / 1024
@property
def mb(self):
return self.kb / 1024
Run Code Online (Sandbox Code Playgroud)
这有效,直到我使用算术运算符:
s = BufferSize(500000)
s.kb
=> 488.28125 # ok
s.mb
=> 0.476837158203125 # ok
type(s + BufferSize(0))
=> int # type lost...
Run Code Online (Sandbox Code Playgroud)
有没有办法确保算术运算保留类型?也就是说,除了覆盖它们中的每一个之外?
或者也许是解决原始问题的另一种更好的方法?
好吧,与其说是重新实现,不如说是包装/转换int的魔术方法的结果,至少是那些返回ints.. 不幸的是,所有这些方法的结果。想知道是否不能使用装饰器或元类来加快速度。
class BufferSize(int):
@property
def b(self):
return int(self)
@property
def kb(self):
return self.b / 1024
@property
def mb(self):
return self.kb / 1024
def __add__(self, *args, **kwds):
return BufferSize(super(BufferSize, self).__add__(*args, **kwds))
v = BufferSize(1) + BufferSize(2)
print v, type(v)
Run Code Online (Sandbox Code Playgroud)
输出:
3 <class '__main__.BufferSize'>
Run Code Online (Sandbox Code Playgroud)
我还考虑过直接将该属性添加到 int 本身,但快速测试排除了这种可能性。
>>> int.b = "b"
Run Code Online (Sandbox Code Playgroud)
输出:
can't set attributes of built-in/extension type 'int'
Run Code Online (Sandbox Code Playgroud)