在Python中重载操作符优add_uu时避免循环依赖

2024-10-01 00:18:28 发布

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

我有一个类消息和一个显然依赖于消息的类消息集合。 我想这样做:

m1 = Message()
m2 = Message()

collection = m1 + m2
isinstance(collection, MessageCollection) # True

问题是我必须在Message类中重载__add__运算符,并在那里创建一个新的MessageCollection实例:

^{pr2}$

从而产生了一个丑陋的循环依赖。有什么办法可以避免吗?也许我的设计是错误的,还有其他方法可以解决这个问题?在

编辑:

我已经重载了MessageCollection的__add__运算符,所以我可以这样做

collection1 = MessageCollection()
collection2 = collection1 + m1 + m2.

我只想让它变得更好。。。在

编辑2:

我最终删除了依赖项,并保留了Message类,没有__add__重载。在

然而。。。。我一直在考虑这个问题,对我来说,有一个语法集合“u objects=object1+object2”是非常有意义的。它表达了“我有一个苹果,然后又买了一个,所以现在我收集了两个苹果”。也许我们应该把一个对象看作是集合的一个特例,其中对象的个数是1?在这种情况下,应该从这个类继承一个对象。。。在

不管怎样,谢谢你们的回答,伙计们!我将把这个问题留待讨论,看是否会引起进一步的争论;)


Tags: 对象实例苹果addtrue消息编辑message
2条回答

我会避免使用MessageCollection并尝试使用常规python列表。他们非常强大,在我看来99%的时间比尝试建立一个新的收集类型更好。在

集合是泛型的,不假设其内容的任何内容,而内容不假设其容器的任何内容,这种想法是非常强大的抽象。除非有非常令人信服的理由,否则你真的应该避免搞砸这件事。在

如果您确实需要MessageCollection类。然后在上面加上__add__运算符。这意味着您构建的MessageCollection为空,可以使用+添加(扩展)。这与list语法类似。在

别再上课了。Really。这是Python中常见的反模式,它在java和C++中对很多人学习的程度较低。部分原因是Java中除了包含类之外什么都没有发生。当你有一个没有状态的类,并且你没有被困在Java中,忘记这个类。在

在爪哇和C++中,创建集合类更重要,因为两种语言都没有列表、集合、序列、字典等。在爪哇/C++中,任何聚合类型都必须编写类,加载库或实例化模板。这增加了编写类的频率:如果我想要一个Message *的向量,那么我必须像您一样创建一个:

collection1 = MessageCollection()
m1 = Message()
m2 = Message()
collection2 = collection1 + m1 + m2

class Message:
    def __add__(self, msg_or_collection):
        if isinstance(msg_or_collection, Message):
            return MessageCollection([self, msg_or_collection])
        elif isinstance(msg_or_collection, MessageCollection)
        return msg_or_collection.append(self)
    raise TypeError("can't add %s to Message" % type(msg_or_collection))

但有一些事情可能会更好。不编写的代码中没有缺陷,更糟糕的是,每次使用isinstance时,您都增加了代码耦合,从而使MessageCollection和Message变得相互缠绕、不可分割。所以我们将删除Message.add这将删除+你非常喜欢的。但是,我们可以避免这种情况,因为除了用于链接消息之外,您没有为消息收集指定任何行为,我们已经可以很容易地做到这一点

^{pr2}$

我们丢失了一个基于多态输入类型的多态返回类型的类方法。我们现在知道了messages.append(m3)的时间复杂性,因为我们非常熟悉列表,并且我们希望对messages进行的所有切片、迭代、操作和更改都已经可用,因为{}是一个列表;MessageCollection可能是。如果不得不使用messages.append(m3)真的让你很沮丧,你仍然有

messages += m3

内置的。在

相关问题 更多 >