从python原始类型派生的类的访问和自定义打印

30 阅读2分钟

我们可能会在python中从一种原始类型(例如float)派生出一种新的类,比如eFloat,以实现自定义表示或特殊行为。但是,在eFloat类中访问原始类型 float 数据时,可能会遇到一些问题。

huake_00210_.jpg 2、解决方案: 访问原始类型数据

class eFloat(float):

    def __repr__(self):
        # "here's my number: %s" % self == "here's my number: %s" % float(self)
        return "here's my number: %s" % str(self)

在这个例子中,我们重写了 repr 方法,用 float.str(self) 或者 self+0 或者 float(self) 获得原始类型的 string 表示。

自定义打印表示

class eFloat(float):

    def __str__(self):
        # "My float is " + float.__str__(self) == "My float is " + str(self)
        return "My float is " + str(self)

print(eFloat(4.5))

在这个例子中,我们重写了 str 方法,用 float.str(self) 或者 self+0 或者 float(self) 获得原始类型的 string 表示,再加上 "My float is "。

完整版自定义类

class eFloat(float):
    """efloat(x) -> floating point number with engineering representation when printed
       Convert a string or a number to a floating point number, if possible.
       When asked to render itself for printing (via str() or print) it is normalized
       to engineering style notation at powers of 10 in multiples of 3
       (for micro, milli, kilo, mega, giga, etc.)        
    """

    def _exponent(self):   
        if self == 0.0:
           ret = 0
        else:
           ret = math.floor(math.log10(abs(self)))
        return ret

    def _mantissa(self):
        return self/math.pow(10, self._exponent())

    def _asEng(self):
        shift = self._exponent() % 3

        retval = "%3.12ge%+d" % (self._mantissa()*math.pow(10, shift), self._exponent() - shift)
        return retval

    def __str__(self):
        return self._asEng()

    def __repr__(self):
        return str(self)

    def __add__(self, x):
        return eFloat(float.__add__(self, float(x)))

    def __radd__(self, x):
        return eFloat(float.__add__(self, float(x)))

    def __mul__(self, x):
        return eFloat(float.__mul__(self, float(x)))

    def __rmul__(self, x):
        return eFloat(float.__mul__(self, float(x)))

    def __sub__(self, x):
        return eFloat(float.__sub__(self, float(x)))

    def __rsub__(self, x):
        return eFloat(float.__rsub__(self, float(x)))

    def __div__(self, x):
        return eFloat(float.__div__(self, float(x)))

    def __rdiv__(self, x):
        return eFloat(float.__rdiv__(self, float(x)))

    def __truediv__(self, x):
        return eFloat(float.__truediv__(self, float(x)))

    def __rtruediv__(self, x):
        return eFloat(float.__rtruediv__(self, float(x)))

    def __pow__(self, x):
        return eFloat(float.__pow__(self, float(x)))

    def __rpow__(self, x):
        return eFloat(float.__rpow__(self, float(x)))

    def __divmod__(self, x):
        return eFloat(float.__divmod__(self, float(x)))

    def __neg__(self):
        return eFloat(float.__neg__(self))

    def __floordiv__(self, x):
        return eFloat(float.__floordiv__(self, float(x)))

这个类实现了将浮点数以工程表示法打印,这样可以方便地表示非常大或非常小的数字。