我有一个值,它在我的代码中以不同的单位使用。例如。表示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
这是有效的,直到我使用算术运算符:
s = BufferSize(500000)
s.kb
=> 488.28125 # ok
s.mb
=> 0.476837158203125 # ok
type(s + BufferSize(0))
=> int # type lost...
有没有办法确保算术运算保留类型?也就是说,除了覆盖它们中的每一个之外?
或许是一种解决原始问题的不同且更好的方法?
答案 0 :(得分:2)
嗯,它并没有像 wrap / cast 那样重新实现int
魔法的结果,至少那些返回{{} 1}} s ..不幸的是,所有这些都是。不知道你是不是可以使用装饰器或元类来加快这种程度。
int
输出:
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)
我还考虑过将属性直接添加到int本身,但快速测试排除了这一点。
3 <class '__main__.BufferSize'>
输出:
>>> int.b = "b"