在Python中修改运算符优先级

12

我已经重载了一些Python操作符,包括算术和布尔操作符。Python的优先级规则仍然有效,这对于重载的操作符来说是不自然的,在表达式中会导致很多括号。是否有一种方法可以“重载”Python的优先级规则?


5
不,这是 Python 语言本身的一部分。这就是语言解析的方式。 - jdi
1
@jdi 这是一个答案,为什么不把它变成一个呢? - kojiro
@kojiro:只是因为我找不到官方Python文档的链接说明它不能被更改。但我找到了很多第三方链接来证明这一点。 - jdi
在实现几何代数时,我遇到了同样的问题,即如何增加异或运算符的优先级。令人惊讶的是,早些时候正是Macdonald教授自己提出了这个问题。 - syockit
2个回答

15

你可以用以下方法欺骗这个机制:

  1. 覆盖所有运算符,不进行计算,而是创建一个包含一些指令的对象列表。
  2. 添加自己的括号运算符(例如作为 _ 函数)。

例子:

>>> a = MyNumber(5); b = MyNumber(2); c = MyNumber(3)
>>> a + b * c
MyExpression([MyNumber(5), '+', MyNumber(2), '*', MyNumber(3)])

括号:

>>> a + _(b * c)

注意,_是一个评估表达式的函数(按照你在其中执行的顺序)。

因此,如果您颠倒优先级,您将获得:

>>> _(a + b * c)
MyNumber(21)

提示:Django也使用QF运算符类似的技巧。


9
不,它是 Python 语言本身的一部分。这就是语言解析的方式。
官方引用:求值顺序 Python 从左到右计算表达式。请注意,在计算赋值时,右侧在左侧之前被计算。
其他引用: Python基础:数字和运算符 在使用混合运算符进行数学运算时,重要的是要注意 Python 根据预先确定的优先顺序决定首先执行哪些运算。这个优先级遵循大多数编程语言的类似优先级。 Python编程/运算符 请注意,Python 遵循 PEMDAS 运算顺序

7
主要问题在于Python在解析代码时会应用运算符优先级。在这个早期阶段,Python不可能知道表达式中实际涉及的对象类型(因为代码尚未执行)。因此,如果可以更改运算符优先级,您将为所有表达式(包括常见数学表达式)进行更改。现在想象一下,如果这是可能的,在标准库和任何第三方库中将会发生什么样的混乱。 - liori
@liori:不错的补充!在同一改变的解释器下,您不能将任何第三方代码与自己的代码混合使用。 - jdi
1
谢谢jdi不仅说明了Python的功能,还解释了为什么我想做的事情不可能实现。 - Alan Macdonald
然而,“不可能”对于Python的极度内省能力来说太难了。请查看下面Tomasz的回答,以了解“覆盖”操作符的想法。简而言之:创建“惰性运算”对象,而不是得到最终结果,并找出执行实际计算所需的触发器。 - jsbueno
1
@jsbueno:我承认有一些方法可以绕过它。但这仍然没有有效地改变Python的运算符优先级。这是将评估推迟到一个你可以干预并以自己的方式进行评估的点。 - jdi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接