由于实现了内置的最大函数

时间:2015-11-20 21:26:41

标签: python

我使用Python来包装一个强大的库(来自另一种语言)来操纵表达式和关系。就此而言,我广泛使用运算符的重载,它就像一个魅力。

现在,我需要定义一个max函数,该函数将应用于我的表达式,以生成一个直观表示“迭代中所有表达式的最大值的新表达式(这些表达式尚未评估)。”< / p>

由于内置函数max使用迭代器和某种实现为__leq__等的顺序关系,(我用它来生成两个表达式的关系)我最终得到了废话我将内置max应用于一组表达式。

更具体地说,

>>> max(e1, e2, e3)
e3

虽然我很想提出某种例外情况说“请使用我的特定功能,我指的是这会产生你合理期望的新表达”

我的底线是,即使我有一个不同的功能实现表达式max

  • 我不想保留此行为,让用户认为他们可以安全max(e1, e2, e3)
  • 我希望max像往常一样使用普通的Python对象。

我能想到的唯一解决方法是从key选项max开始,当它遇到特定类型的对象时引发异常:

def newkey(p):
    if isinstance(p, Expression):
        raise SyntaxError("Use function `foo` for computing `max`")
    # fallback to regular behaviour I know nothing about yet

max(e1, e2, e3, key=newkey)

现在,我无法强制用户在每次调用key时指定max选项。事实上,如果可以,我会告诉他们使用不同的max功能......

你能看出一条出路吗? (或更好的解决方法)

2 个答案:

答案 0 :(得分:2)

  

由于内置函数max使用迭代器和某种实现为__leq__等的顺序关系(我用它来生成两个表达式的关系)

丰富的比较方法返回的类型需要在Python 3中实现__nonzero____bool__,以定义当您尝试将其解释为布尔值时会发生什么。 __nonzero__应该做什么有两种合理的可能性。

如果实际评估基础表达式并执行比较是合理的,您可以设计__nonzero__方法来做到这一点。如果您正在构建某种惰性操作库,这将是有意义的。在这种情况下,max只会起作用,但它会隐含地强制评估其论点。这可能不太可取。

或者,您可能会__nonzero__引发TypeError。在这种情况下,当max试图决定两个表达式中哪一个更大时,它会引发一个TypeError。

答案 1 :(得分:0)

您可以使用装饰器覆盖max它将提供相同的行为但在需要时引发异常检查以下代码

def dec(ff):
    def _f(*args):
        for p in args:
            if isinstance(p, Expression):
                raise SyntaxError("Use function `foo` for computing `max`")
        else:
            return ff(*args)
    return _f

max = dec(max)