python“in”运算符反映了魔术方法

时间:2018-06-02 10:31:03

标签: python

|运算符有两种魔术方法,正常和反射。

# object + other
__or__(self, other)
    # Implements bitwise or using the | operator.

# other + object
__ror__(self, other)
    # Implements reflected bitwise or using the | operator.

in运算符只有一种魔术方法。

# item in object
__contains__(self, item)
    # __contains__ defines behavior for membership tests using in and not in.

如何实施in运营商反映的魔法?

# object in sequence
__rcontains__(self, sequence):
    # defines behavior for self in or not in sequence

当您想要实现sql条件

时,它会很有用
class Field(object):
    def __lt__(self, other):
        return '<', self._value, other

Model.objects.filter(Field('a') > 1)
Model.objects.filter(Field('a') in [1, 2, 3, 4])

1 个答案:

答案 0 :(得分:1)

你不能,因为in运算符在语义上与对象“包含”另一个对象的定义有关。因此,必须在容器类(此处为list)中定义操作,而不是值(Field)。

为了说明,您的案例中的in应该像这样使用:

Field('a') in [Field('a'), Field('b'), Field('c')]

当然,这不是你想要的。

正如您在评论中提到的那样,您最接近您想要的是使用Django的fieldname__in==[1, 2, 3, 4]或SQLAlchemy的Table.fieldname.in_([1, 2, 3, 4])之类的东西。例如,您可以向Field添加方法:

Field('a').is_in([1, 2, 3])

另一种方法是创建一个特定的容器类,以便编写:

Field('a') in Values([1, 2, 3])

但它不仅更加冗长(需要额外的导入),我认为更难理解背后的真实情况。

这也有效:

Field('a') == [1, 2, 3]

但同样,它感觉更“神奇”而且令人困惑,因为它不尊重==的语义。