Python 2.7中能否让__contains__父类方法接收3个参数?自定义实现遇问题
一、自定义__contains__实现区间判断的正确方式
首先得明确:Python中__contains__方法的签名是固定的,只能接收两个参数:self(实例本身)和other(in操作符左边传入的值)。你尝试给它加第三个参数other2是不符合Python语法规范的,这也是运行print 1 in x时报错的核心原因——in操作只会给__contains__传两个参数(self和1),但你的方法定义要求三个参数,直接触发了参数不匹配的TypeError。
要实现“判断实例的item值介于两个整数之间返回True”的需求,我们可以换个思路:让in左边传入一个包含两个整数的元组/列表,然后在__contains__里解析这个参数。示例代码如下:
class test(object): def __init__(self, item): self.item = item def __contains__(self, other): # 先校验传入的参数是否是合法的区间格式 if isinstance(other, (list, tuple)) and len(other) == 2: lower, upper = other return lower < self.item < upper # 可选:保留单个值的匹配逻辑,兼容常规in操作 return self.item == other x = test(5) print((1, 10) in x) # 输出True print(5 in x) # 输出True print((6, 8) in x) # 输出False
这样既满足了区间判断的需求,又完全符合Python的语法规则。
二、Python 2.7中__contains__的super方法能否接收3个参数?
答案是绝对不行。不管是你自己定义的__contains__,还是调用父类(比如object类)的__contains__,这个特殊方法的签名都是固定的def __contains__(self, other):,只能接受两个参数。
Python的特殊方法(像__contains__、__eq__这类)的参数个数是由语言规范硬性规定的,不能随意修改。你尝试给它传三个参数的话,不管是直接调用还是通过super调用,都会触发参数不匹配的异常。
补充:你原来的代码运行时,执行
1 in x会调用x.__contains__(1),但你的方法定义要求三个参数,所以直接抛出TypeError: __contains__() takes exactly 3 arguments (2 given)——这和super方法无关,纯粹是你的方法本身定义不符合规范导致的。
内容的提问来源于stack exchange,提问作者Hayden

