Python - 不可变类型示例

时间:2011-11-03 08:34:44

标签: python

有人可以告诉我如何使用这段代码吗?我不确定我想问的是什么问题,我只想定义需要使用它的类以及我可以提供给解释器的其他命令。

这真的让我头疼,因为没有其他支持代码,我认为它可能是元类用法。

谢谢,

class RoundFloat(float):
    def __new__(cls, val):
        return float.__new__(cls, round(val, 2))

5 个答案:

答案 0 :(得分:4)

这里没什么可疯狂的。我会发表评论。虽然它的格式应该是这样的:

# Inherit from the built in type 'float', 
# so that this can be used anywhere a float can
class RoundFloat(float):
    # __new__ takes care of actually creating the object
    def __new__(cls, val):
        # Pass it off to the float initializer, but round the value first
        return float.__new__(cls, round(val, 2))

这实际上只是一种实现浮点值的快速方法,浮点值总是舍入到2位小数。

答案 1 :(得分:4)

名为__new__的方法是该类的构造函数。不要将它与__init__混淆,后者是类初始化者;不同之处在于,在拥有对象的实例之前调用__new__,并且必须创建并返回实例,而在创建对象后调用__init__

通常在子类化时,只需覆盖初始化器来进行自己的初始化,但如果您继承了不可变对象,则通常不起作用,因为在构造对象后无法更改对象的实际值。在这种情况下,代码正在改变float的构造方式,因此它会覆盖float.__new__,然后使用修改后的参数显式调用它。

整个课程完全浪费时间,如果你想创建一个圆形浮动,只需这样做:

def rounded_float(f): return round(f, 2)

或:

from functools import partial
rounded_float = partial(round, ndigits=2)

并且在任何一种情况下,对rounded_float的调用都会返回舍入为2位的值。 还要记住,当您使用rounded_float(1.0/3.0)未准确给出0.33的函数时,它只会为您提供最近的浮点表示。如果您想要计算目的的确切值,请使用Decimal类,但如果是输出,则只需格式化输出中的数字。

答案 2 :(得分:2)

首先,我看到的缩进是不正确的。方法(构造函数)定义应缩进:

class RoundFloat(float):
    def __new__(cls, val):
        return float.__new__(cls, round(val, 2))

其次,要使用它,你可以写出类似的东西:

a = RoundFloat(3.1236589)

然后如果你这样做:

print a

您将收到:

  

3.12

这是应该在这里预期的(意味着:是正确的行为)。

这是你要的吗?让我知道。

答案 3 :(得分:1)

你这样使用它:

a = RoundFloat(10.256)

如果你现在打印一个:

10.26

答案 4 :(得分:1)

如果您希望所有数字实例都是舍入浮点数,那么定义的类 RoundFloat 就可以了:数字将显示为舍入浮点数并且 BE 舍入浮点数。
这意味着如果您执行涉及两个这样的数字的操作,例如+ - x /,则操作的结果将不是涉及未舍入值的结果的舍入值。

也许这就是你想要的。

但如果您愿意:

1)使用保持精确值的数字 ,同时以圆角方式显示,您必须覆盖__str__

2)涉及两个此类实例的操作的结果,以给出一个数字本身就是这样的实例,您还必须覆盖操作__add____div__

你必须采取其他方式,例如下面定义的 Floot 类。

以下代码比较了两种情况下的添加结果。

class Floot(float):
    cut = 4
    def __init__(self,x):
        self = x
    def __str__(self):
        return ('%%.%df' % Floot.cut) % self
    def __add__(self,y):
        return Floot(super(Floot,self).__add__(y))
    def __sub__(self,y):
        return Floot(super(Floot,self).__sub__(y))
    def __div__(self,y):
        return Floot(super(Floot,self).__div__(y))
    def __mul__(self,y):
        return Floot(super(Floot,self).__mul__(y))
    def __pow__(self,y):
        return Floot(super(Floot,self).__pow__(y))


class RoundFloat(float):
    def __new__(cls, val):
        return float.__new__(cls, round(val, 4))


a = 5.1275407
b = 0.7003208


print 'class Floot\n***********'

aa = Floot(a)
print 'a                : ',a
print 'aa = Floot(a)    : ',aa

bb = Floot(b)
print '\nb                : ',b
print 'bb = Floot(b)    : ',bb

c  = a+b
cc = aa + bb
print '\nc  = a + b       : ',c
print 'cc = aa+bb       : ',cc

print '\nround(c ,4)      : ',round(c,4)
print 'round(cc,4)      : ',round(cc,4)

print ('\nc  - round(c ,4) : %.10f' % (c  - round(c ,4)) ).rstrip('0')
print ('cc - round(cc,4) : %.10f' % (cc - round(cc,4)) ).rstrip('0')




print '\n\nclass RoundFloat\n****************'

aa = RoundFloat(a)
print 'a                   : ',a
print 'aa = RoundFloat(a)  : ',aa

bb = RoundFloat(b)
print '\nb                   : ',b
print 'bb = RoundFloat(b)  : ',bb

c  = a+b
cc = aa + bb
print '\nc  = a + b          : ',c
print 'cc = aa+bb          : ',cc

print '\nround(c ,4)         : ',round(c,4)
print 'round(cc,4)         : ',round(cc,4)

print ('\nc  - round(c ,4)    : % .10f' % (c  - round(c ,4)) ).rstrip('0')
print ('cc - round(cc,4)    : % .10f' % (cc - round(cc,4)) ).rstrip('0')

尽管Floot(5.1275407)显示为5.1275而Floot(0.7003208)显示为0.7003,但Floot(5.1275407)+ Floot(0.7003208)显示为5.8279的事实背叛了这些Floot的真实值这一事实实例比它们的显示更精确。

cc - round(cc,4)具有与c - round(c,4)相同的值的事实背叛了相同的事实: Floot(a)+ Floot(b) a + b 实际上具有相同的值