我正在努力在我的类中自定义 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'
这是一个 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 之禅:“显式优于隐式。简单优于复杂。”