在python中将属性添加到int值

时间:2017-01-07 20:14:27

标签: python inheritance properties int operators

我有一个值,它在我的代码中以不同的单位使用。例如。表示BYTES数量的缓冲区大小,但在许多地方将大小称为KB或MB(这只是一个示例,而不是我的实际用例)。

为了优雅和易用,我希望避免显式转换(例如size/1024b_to_mb(size)),因为在很多不同的地方都需要它们。

我认为我可以通过属性实现这一点,这使得转换变得容易(x.kbx.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...

有没有办法确保算术运算保留类型?也就是说,除了覆盖它们中的每一个之外?

或许是一种解决原始问题的不同且更好的方法?

1 个答案:

答案 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"