如何获取触发Python特殊方法的运算符名称?
解决Python自定义类特殊方法中避免硬编码运算符名称的问题
核心问题分析
你的代码中__ge__方法通过not self < other调用__lt__,但__lt__里硬编码了运算符'<',导致执行you >= 30时错误消息显示的是'<'而非实际触发的'>='。要解决这个问题,需要让错误消息自动匹配当前触发的运算符,避免手动硬编码。
可行解决方案
方案1:类属性映射+inspect模块动态获取方法名
定义类级别的字典,将特殊方法名映射到对应的运算符字符串,再通过inspect模块获取当前执行的方法名,动态匹配运算符:
import inspect class Person: # 特殊方法与运算符的映射表 OP_MAP = { '__lt__': '<', '__le__': '<=', '__gt__': '>', '__ge__': '>=', '__eq__': '==', '__ne__': '!=' } def __init__(self, name, age): self.name = name self.age = age def __lt__(self, other): if not isinstance(other, Person): # 获取当前执行的方法名 current_method = inspect.currentframe().f_code.co_name op = self.OP_MAP[current_method] raise TypeError(f"'{op}' not supported between instances of " f"'{type(self).__name__}' and '{type(other).__name__}'") return self.age < other.age def __ge__(self, other): if not isinstance(other, Person): current_method = inspect.currentframe().f_code.co_name op = self.OP_MAP[current_method] raise TypeError(f"'{op}' not supported between instances of " f"'{type(self).__name__}' and '{type(other).__name__}'") return not self < other
方案2:封装异常抛出逻辑减少重复代码
把获取运算符、抛出异常的逻辑封装成私有方法,避免在每个特殊方法中重复编写:
import inspect class Person: OP_MAP = { '__lt__': '<', '__le__': '<=', '__gt__': '>', '__ge__': '>=', '__eq__': '==', '__ne__': '!=' } def __init__(self, name, age): self.name = name self.age = age def _raise_type_error(self, other): # 回溯到调用当前方法的特殊方法帧 current_method = inspect.currentframe().f_back.f_code.co_name op = self.OP_MAP[current_method] raise TypeError(f"'{op}' not supported between instances of " f"'{type(self).__name__}' and '{type(other).__name__}'") def __lt__(self, other): if not isinstance(other, Person): self._raise_type_error(other) return self.age < other.age def __ge__(self, other): if not isinstance(other, Person): self._raise_type_error(other) return not self < other
方案3:装饰器统一处理异常逻辑
使用装饰器给每个特殊方法绑定对应的运算符,集中管理异常抛出逻辑:
import functools def operator_error_handler(op): def decorator(func): @functools.wraps(func) def wrapper(self, other): if not isinstance(other, Person): raise TypeError(f"'{op}' not supported between instances of " f"'{type(self).__name__}' and '{type(other).__name__}'") return func(self, other) return wrapper return decorator class Person: def __init__(self, name, age): self.name = name self.age = age @operator_error_handler('<') def __lt__(self, other): return self.age < other.age @operator_error_handler('>=') def __ge__(self, other): return not self < other
验证效果
现在执行you >= 30,错误消息会正确显示:'>=' not supported between instances of 'Person' and 'int',与实际触发的运算符一致。
内容的提问来源于stack exchange,提问作者Javier Abad
相关产品推荐
相关产品推荐

