I am working in customizing the behaviour of Python native functions and operators in my classes. I would like to avoid hard coding when printing error messages like "'<' not supported between instances of 'int' and 'str'".
I know how to avoid hard coding of type names (by using type(object).__name__
. But ¿how can I refer to the native function or operator that triggered my customized special method?
Here it comes an easy example:
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
With this class definition I have:
>>> 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'
>>>
As you can see, I had to hardcode the name of the operator '<'. I usually avoid hard coding, but in this case I have an additional reason to avoid it: the TypeError message in operator >= is wrong as it says: '<' not supported between instances of 'Person' and 'int'
you could achieve this by defining an
operator
variable and then setting it to whatever it should be based on the conditions.So something like this:
You would need to pass the equivalent of this into whatever classes you decide to use this way.