我可以获取触发特殊方法的操作员的名称吗?

问题描述 投票:0回答:1

我正在努力在我的类中自定义 Python 本机函数和运算符的行为。我想在打印“'<' not supported between instances of 'int' and 'str'". I know how to avoid hard coding of type names (by using

type(object).__name__
”之类的错误消息时避免硬编码。但是,我如何引用触发我的自定义特殊方法的本机函数或运算符?

这是一个简单的例子:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __lt__(self, other):
        if not isinstance(other, Person):
            raise TypeError("'<' not supported between instances of "
                            f"'{type(self).__name__}'"
                            f" and '{type(other).__name__}'")
        else:
            return self.age < other.age
        
    def __ge__(self, other):
        return not self < other

通过这个类定义,我有:

>>> me = Person('Javier', 55)
>>> you = Person('James', 25)
>>> print(you < me)
True
>>> print(you >= me)
False
>>> print(you < 30)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "....py", line 8, in __lt__
    raise TypeError("'<' not supported between instances of "
TypeError: '<' not supported between instances of 'Person' and 'int'
>>> print(you >= 30)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "....py", line 15, in __ge__
    return not self < other
  File "....py", line 8, in __lt__
    raise TypeError("'<' not supported between instances of "
TypeError: '<' not supported between instances of 'Person' and 'int'
>>> 

如您所见,我必须对运算符的名称进行硬编码 '<'. I usually avoid hard coding, but in this case I have an additional reason to avoid it: the TypeError message in operator >= 是错误的,因为它说:'<' not supported between instances of 'Person' and 'int'

python magic-methods hardcode
1个回答
-1
投票

这是一个 XY 问题:您询问如何获取触发特殊方法的运算符,但实际上您真正想要做的是在错误消息中提供正确的运算符。您决定以某种方式找到您需要的接线员并询问此事。没有办法做到这一点。

在这种情况下,我会编写

__lt__
方法,以便它接受可选的第三个参数:

def __lt__(self, other, op="<"):
    if not isinstance(other, Person):
        raise TypeError(f"'{op}' not supported between instances of "
                        f"'{type(self).__name__}'"
                        f" and '{type(other).__name__}'")

然后编写您的

__ge__
运算符以显式调用此方法(而不是隐式使用
<
)并传入您希望出现在错误消息中的运算符:

def __ge__(self, other):
    return not self.__lt__(other, ">=")

Python 之禅:“显式优于隐式。简单优于复杂。”

© www.soinside.com 2019 - 2024. All rights reserved.