位逆与位的组合

2024-09-30 01:20:50 发布

您现在位置:Python中文网/ 问答频道 /正文

给定以下类别:

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']}

Tags: orimportselfreturnfoodefnot类别
3条回答

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

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

在这种情况下,需要重载__ror__。有关Python如何计算运算符的详细信息,请参见this post

基本上,这种说法

operator.__or__(~x, y)

与相同

x.__invert__().__or__(y)

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

y.__ror__(x.__invert__())

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

根据我应该返回Foo实例的注释提供另一个答案

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'}]}

相关问题 更多 >

    热门问题