在python类上重写_或_运算符
作为一个人为的例子,假设我正在用python生成一个随机的果篮。我创建了一个篮子:在python类上重写_或_运算符,python,operator-overloading,Python,Operator Overloading,作为一个人为的例子,假设我正在用python生成一个随机的果篮。我创建了一个篮子: basket = FruitBasket() 现在我想指定篮子中可能出现的水果的特定组合。假设我是一个非常挑剔的家伙,篮子里要么装满苹果、石榴、桔子和葡萄柚,要么只有香蕉 我在阅读python操作符重载,似乎我可以定义\uuuuu或类别(类型): ... 定义或(自身、其他): ... 返回或(自身、其他) ... >>>类水果(对象): ... __元类\水果元 ..
basket = FruitBasket()
现在我想指定篮子中可能出现的水果的特定组合。假设我是一个非常挑剔的家伙,篮子里要么装满苹果、石榴、桔子和葡萄柚,要么只有香蕉
我在阅读python操作符重载,似乎我可以定义\uuuuu或
和\uuu和
来获得我想要的行为。我想我可以这样做:
basket.fruits = (Apple() & Pomegranate()) | (Banana()) | (Orange() & Grapefruit())
TypeError: unsupported operand type(s) for |: 'type' and 'type'
这在创建两个类(或
和和
)时非常有效。当调用\uuuuu或\uuuuu和时,我只需返回一个新的或或和对象:
def __or__(self, other):
return Or(self, other)
def __and__(self, other):
return And(self, other)
我想弄明白的是,我如何做到这一点,而不必先实例化水果?为什么我不能在baseFruit
类上使用静态的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu或
方法?我试过这个,但不起作用:
class Fruit(object):
@classmethod
def __or__(self, other):
return Or(self, other)
分配水果:
basket.fruits = (Apple & Pomegranate) | (Orange & Grapefruit) | (Banana)
我得到一个类似这样的错误:
basket.fruits = (Apple() & Pomegranate()) | (Banana()) | (Orange() & Grapefruit())
TypeError: unsupported operand type(s) for |: 'type' and 'type'
关于如何实现这一点有什么想法吗?您不能将特殊(hook)方法作为类方法添加到类中,因为它们总是根据当前对象的类型进行查找;对于类中的实例,对于类,将在type
上查找它们。请参阅,了解其动机,了解其原因
这意味着您需要在服务器上实现这一点;元类充当类的类型:
class FruitMeta(type):
def __or__(cls, other):
return Or(cls, other)
def __and__(cls, other):
return And(cls, other)
然后对于Python 3:
class Fruit(metaclass=FruitMeta):
或Python 2:
class Fruit(object):
__metaclass__ = FruitMeta
\uuuu或uuu
是根据对象的类型查找的;对于水果
实例,这将是水果
;对于水果
,即类型
。不过,您可以使用元类更改水果的类型:
class FruitMeta(type):
def __or__(self, other):
return Or(self, other)
class Fruit(object):
__metaclass__ = FruitMeta
(对于Python3,语法是classfruit(metaclass=FruitMeta):
这样你就可以随心所欲了Apple | Banana
(假设这两个是Fruit
的子类)将产生或(Apple,Banana)
不过,对这种设计要非常小心。它倾向于魔法领域,很容易引起混乱
(完整演示,使用Python 2.7:)
类或(对象):
... 定义初始化(self,a,b):
... self.a=a
... self.b=b
... 定义报告(自我):
... 返回'Or({!r},{!r})'.format(self.a,self.b)
...
>>>类别(类型):
... 定义或(自身、其他):
... 返回或(自身、其他)
...
>>>类水果(对象):
... __元类\水果元
...
>>>苹果(水果)班:及格
...
>>>香蕉(水果)班:通过
...
>>>苹果香蕉
或(,)
正是我想要找到的!谢谢效果很好