为什么不能为非浮动定义'round`?

时间:2013-04-17 11:14:02

标签: python class python-2.7 rounding

给出一个像

这样的简单类
class Vector(object):
    def __init__(self, value):
        self.value = value
    def __abs__(self):
        return math.sqrt(sum([x**2 for x in self.value]))
    def __round__(self, *n):
        return [round(x,*n) for x in self.value]

为什么abs(Vector([-3,4]))正确地5 round(Vector([-3.1,4]))TypeError: a float is required抱怨[-3,4]而不是期望的round,以及如何解决?

我知道numbers.Real通常应该返回一个浮点数,但是对于这个例子中的向量,可能含义可能没有歧义,为什么不能简单地重写?我真的必须继承Vector(...).round(n),或者定义{{1}}吗?

1 个答案:

答案 0 :(得分:6)

{3}只在Python 3中引入了__round__特殊方法。不支持Python 2中的特殊方法。

您必须使用专用方法而不是函数:

class Vector(object):
    def __init__(self, value):
        self.value = value

    def round(self, n):
        return [round(x, n) for x in self.value]

或者您必须提供自己的round()功能:

import __builtin__

def round(number, digits=0):
    try:
        return number.__round__(digits)
    except AttributeError:
        return __builtin__.round(number, digits)

你甚至可以将其修补到__builtins__名称空间:

import __builtin__

_bltin_round = __builtin__.round

def round(number, digits=0):
    try:
        hook = number.__round__
    except AttributeError:
        return _bltin_round(number, digits)
    else:
        # Call hook outside the exception handler so an AttributeError 
        # thrown by its implementation is not masked
        return hook(digits)

__builtin__.round = round