Python值与单位

时间:2009-12-05 16:54:14

标签: python

我需要在Python中跟踪float和int值的单位,但我不想使用像scale或其他类似的外部包,因为我不需要对值执行操作。相反,我想要的是能够定义具有单位属性的浮点数和整数(我不想为这么简单的东西添加新的依赖关系)。我试过了:

class floatwithunit(float):

    __oldinit__ = float.__init__

    def __init__(self, *args, **kwargs):
        if 'unit' in kwargs:
            self.unit = kwargs.pop('unit')
        self.__oldinit__(*args, **kwargs)

但这根本不起作用:

In [37]: a = floatwithunit(1.,unit=1.)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

/Users/tom/<ipython console> in <module>()

TypeError: float() takes at most 1 argument (2 given)

Any suggestions?

5 个答案:

答案 0 :(得分:8)

你可能正在寻找这样的东西:

class UnitFloat(float):

    def __new__(self, value, unit=None):
       return float.__new__(self, value)

    def __init__(self, value, unit=None):
        self.unit = unit


x = UnitFloat(35.5, "cm")
y = UnitFloat(42.5)

print x
print x.unit

print y
print y.unit

print x + y

收率:

35.5
cm
42.5
None
78.0

答案 1 :(得分:6)

您需要覆盖__new__(“构造函数正确”,而__init__是“初始化程序”),否则float的{​​{1}}会被外部参数调用,这是你所看到的问题的原因。你不需要调用float的__new__(这是一个无操作)。这是我编码的方式:

__init__

发出class floatwithunit(float): def __new__(cls, value, *a, **k): return float.__new__(cls, value) def __init__(self, value, *args, **kwargs): self.unit = kwargs.pop('unit', None) def __str__(self): return '%f*%s' % (self, self.unit) a = floatwithunit(1.,unit=1.) print a

答案 2 :(得分:1)

我认为你的意思是

class floatwithunit(float):

而不是

def floatwithunit(float):

答案 3 :(得分:0)

Alex Martelli确实指出了问题的根源。我总是觉得__new__很混乱,所以这里有一段示例代码:

class FloatWithUnit(float):
    def __new__(cls, *args, **kwargs):
        # avoid error in float.__new__
        # the original kwargs (with 'unit') will still be passed to __init__
        if 'unit' in kwargs:
            kwargs.pop('unit')
        return super(FloatWithUnit, cls).__new__(cls, *args, **kwargs)

    def __init__(self, *args, **kwargs):
        self.unit = kwargs.pop('unit') if 'unit' in kwargs else None
        super(FloatWithUnit, self).__init__(*args, **kwargs)

答案 4 :(得分:-2)

在您尝试查看是否有标签'unit'之前,您似乎需要检查kwargs是否为None。

将您的代码更改为

 if kwargs and 'unit' in kwargs:

更新回答:

don't pass kwargs to __oldinit__