将按位逆与按位或结合

combining bitwise inverse with bitwise or

给出以下 class:

import operator
class Foo(object):
    def __init__(self, bah):
        self.bah = bah      

    def __invert__(self):
        return {'not': self.bah}

    def __repr__(self):
        return self.bah

    def __or__(self, other):
        return {'or': [self.bah, other]}    


x = Foo('obj1')
y = Foo('obj2')

我能做到:

operator.inv(x) # ~x

这给了我:

{'not': 'obj1'}

我能做到:

operator.or_(x, ~y) # x | ~y

这给了我:

{'or': ['obj1', {'not': 'obj2'}]}

但是为什么我做不到:

operator.or_(~x, y) # ~x | y

这会引发以下错误:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-175-92fdd35dc3b3> in <module>
----> 1 operator.or_(~x, y)

TypeError: unsupported operand type(s) for |: 'dict' and 'Foo'

我怎样才能输出以下内容?

{'or': [{'not': 'obj1'}, 'obj2']}

operator.or_() 调用似乎在查找您提供的 first 参数中定义的 __or__ 方法。这就是为什么在 operator.or_(x, ~y) 情况下它工作正常 - x 是包含 __or__ 的 Foo 对象。定义。

在第二种情况下,operator.or_(~x, y),然而,~x 的输出是一个不包含 __or__ 定义的字典 {'not': 'obj1'}

在这种情况下,您需要重载 __ror__。有关 Python 如何评估运算符的详细信息,请参阅

基本上就是这个说法

operator.__or__(~x, y)

相同
x.__invert__().__or__(y)

由于 __or__ 没有为 x.__invert__() 返回的 dict 对象定义,调用失败。定义 __ror__ 会使 Python 解释器尝试计算

y.__ror__(x.__invert__())

在第一次尝试失败后 ~x | y

根据评论提供另一个答案,我应该是 Foo

的 return 个实例
class Foo(object):
    def __init__(self, name):
        self.name = name      

    def __invert__(self):
        return Foo({'not': self.name})

    def __repr__(self):
        return str(self.name)

    def __or__(self, other):
        return Foo({'or': [self.name, other]})

    def __and__(self, other):
        return Foo({'and': [self.name, other]})   


x = Foo('obj1')
y = Foo('obj2')

有了这个我可以做到:

>>> operator.or_(~x, y) # ~x | y
{'or': [{'not': 'obj1'}, 'obj2']}

甚至

>>> operator.or_(~x, ~y) # ~x | ~y
{'or': [{'not': 'obj1'}, {'not': 'obj2'}]}