__contains__是否可以返回非布尔值?

时间:2018-11-17 13:48:52

标签: python

文档说__contains__ 应该如果项是自已的,则返回true,否则返回false。但是,如果该方法返回非布尔值x,则python似乎会自动将其转换为bool(x)

有什么办法可以避免这种情况,并返回实际值x?还是该功能行为直接在解释器中实现,并且无法更改?

4 个答案:

答案 0 :(得分:6)

请注意,不是__contains__将该值转换为布尔值,而是调用 in的{​​{1}}运算符。与

__contains__

答案 1 :(得分:4)

对于CPython3,foo in bar将被编译为COMPARE_OP (in)。该实现使用PySequence_Contain(),然后使用coerces得出bool。因此,当您可以返回其他内容时,您always会在通话后以布尔值结束。

答案 2 :(得分:4)

在Python文档中,第6.10.2. Membership test operations节说:

  

对于定义__contains__()方法的用户定义类,modprobbe   如果x in y返回真值,则返回True,并且y.__contains__(x)返回False   否则。

很显然,如果返回非布尔值,in运算符仍将返回布尔值。

如果您直接致电__contains__,那么您当然会得到返回的结果。

例如:

class X:
    def __contains__(self, other):
        return 11

x = X()

8 in x  #  True

x.__contains__(8)  # 11

答案 3 :(得分:3)

实际上,在返回值__bool__上调用了

__contains__

请考虑以下课程:

class BoolWithPrint:
    def __init__(self, value):
        self.value = value
    def __bool__(self):
        print("Im being booled.")
        return self.value

class StrangeContains:
    def __contains__(self, x):
        return BoolWithPrint(x)

...的行为如下:

>>> True in StrangeContains()
Im being booled.
True
>>> False in StrangeContains()
Im being booled.
False
>>> 'stuff' in StrangeContains()
Im being booled.
[...]
TypeError: __bool__ should return bool, returned str

据我所知,您不走运。您可以在值__bool__上偷偷覆盖__contains__,但这只会延迟TypeError,因为__bool__必须返回TrueFalse

有关其他上下文,请参见Can the Python bool() function raise an exception for an invalid argument?