如何在Python中设置__contains__方法?

3
我有点难以理解如何在我的类中正确设置contains方法。我知道当调用它时,它会自动使用运算符in,但我不确定如何正确设置它。
我必须使用它来查看另一个圆是否包含在特定圆内(两者均由用户输入)。教授要求我们为此做两种不同类型的方法。
第一种方法我没有问题,更或多或少地了解其作用,如下所示:
def contains(self, circle2d):
  dist = math.sqrt((circle2d._x - self._x)**2 + (circle2d._y - self._y)**2) #Distance of second circle's coords from the first circle's coords
  if dist + circle2d._radius <= self._radius:
     return True

然而,下一个方法将使用contains方法来实现同样的功能,以便我们可以在主函数中使用in调用它。这是我所拥有的全部内容:
def __contains__(self, anotherCircle):
    if anotherCircle in self:
        return True 

当我尝试运行这个程序时,出现了多个错误。我认为我在self上漏掉了一些东西,但我不确定是什么?能否有人请尝试向我解释一下,当你编写像这样的包含方法时,需要做什么?


如果anotherCircle self不就是在自身调用__contains__吗?方法体中应该不是应该使用return self.contains(anotherCircle)吗? - huggie
我不知道。我猜那就是我所问的。 - A Computer
当你在__contains__内部使用"in"时,你正在递归调用__contains__ - huggie
是的,你说的确实有效!谢谢。 - A Computer
2个回答

10

对象上的__contains__方法并不会调用in;相反,它是in操作符调用的方法。

当您编写以下代码时:

if circle1 in circle2:

Python解释器会发现circle2是一个圆对象,并查找为其定义的__contains__方法。实质上它将尝试调用该方法。
circle2.__contains__(circle1)

这意味着你需要编写你的__contains__方法,而不使用in,否则你将写一个永远不会结束的递归方法。

好的,如果in调用了contain方法,那么你如何编写被in调用的方法呢? - A Computer
你可以像编写原始的 contains 方法一样编写代码 -- 里面的代码看起来就是你需要的 -- 只是如果 self 不包含 circle2d,你可能想要返回 False。 - Ian Clelland

1
你的__contains__方法必须使用与原始contains方法相同的逻辑。否则,Python怎么知道一个圆包含另一个圆是什么意思?你必须告诉它,这就是__contains__方法的作用。你可以让__contains__调用contains,或者直接将整个代码放在该方法中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接