由于内置max函数的实现而导致的Python设计问题

由于内置max函数的实现而导致的Python设计问题,python,Python,我使用Python包装了一个功能强大的库(来自另一种语言),用于处理表达式和关系。就这一点而言,我广泛使用运算符重载,它的工作方式很有魅力 现在,我需要定义一个max函数,该函数将应用于我的表达式,以生成一个新表达式,直观地表示“iterable中所有表达式的max(这些表达式尚未计算)” 由于内置函数max使用迭代器和某种实现为\uuuleq\uuuuu等的顺序关系(我使用它从两个表达式生成关系),因此当我在一组表达式上应用内置的max时,我最终会变得毫无意义 更具体地说 >>&g

我使用Python包装了一个功能强大的库(来自另一种语言),用于处理表达式和关系。就这一点而言,我广泛使用运算符重载,它的工作方式很有魅力

现在,我需要定义一个
max
函数,该函数将应用于我的表达式,以生成一个新表达式,直观地表示“iterable中所有表达式的max(这些表达式尚未计算)”

由于内置函数
max
使用迭代器和某种实现为
\uuuleq\uuuuu
等的顺序关系(我使用它从两个表达式生成关系),因此当我在一组表达式上应用内置的
max
时,我最终会变得毫无意义

更具体地说

>>> max(e1, e2, e3)
e3
尽管我想提出一些例外,比如“请使用我在这里指出的特定函数,它将生成您合理期望的新表达式”

我的底线是,即使我有一个不同的函数为表达式实现
max

  • 我不想让这种行为保持现状,让用户认为他们做
    max(e1、e2、e3)
    是安全的
  • 我希望
    max
    像往常一样处理常规Python对象
我能想到的解决此问题的唯一方法是,在命中特定类型的对象时,通过欺骗
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)
现在,我无法强制用户在每次调用
max
时指定
选项。事实上,如果可以,我会告诉他们使用不同的
max
函数


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

您可以使用装饰器覆盖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)
因为内置函数max使用迭代器和某种顺序关系,实现为
\uuuleq\uuuu
等(我使用它从两个表达式生成关系)

富比较方法返回的类型需要在Python3中实现
\uuuu nonzero\uuu
\uuu bool\uuuu
,以定义尝试将其解释为布尔值时发生的情况。有两种合理的可能性来说明
\uuu非零\uuu
应该做什么

如果实际计算底层表达式并执行比较是合理的,那么您可以设计
\uuu nonzero\uuu
方法来实现这一点。如果您正在构建某种懒惰的操作库,这将是有意义的。在这种情况下,
max
只会起作用,但它会隐式地强制对其参数进行求值。这可能不可取


或者,您可以让
\uuuuu非零\uuuu
引发类型错误。在这种情况下,当
max
试图确定两个表达式中哪一个更大时,它将引发一个类型错误。

为什么会出现无意义的结果?为什么不正确地实现
\uuuuuleq\uuuuuuu
?因为
\uuuuuuuuu
返回一个
关系的实例,该实例尚未计算(因为表达式尚未计算),并且既不是
真的
也不是
假的
。在
关系
上定义
\uuuuu bool\uuuuu
,因此将对其进行计算。或者
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。您可以为此行为进行设计,然后将
lazy_max
函数添加到模块中,以返回
LazyMax
对象。这涵盖了你所有的基础。我相信你不会,因为这没有意义这不仅仅是懒惰的评估。