【发布时间】:2021-03-25 16:30:01
【问题描述】:
我希望实现以下内容。有一个类foo,其中包含infoo 对象的列表。我在想,为了重载 __add__ 运算符,我应该
class foo(object):
def __init__(self, infoo_list):
self.args = infoo_list
def __add__(self, other):
if isinstance(other, type(self)):
newargs = self.args + other.args
return foo(newargs)
elif isinstance(other, infoo_type):
newargs = self.args + [other]
return foo(newargs)
class infoo (object):
def __init__(self):
pass
def __add__(self, other):
return foo([self, other])
infoo_type = type(infoo())
如您所见,foo 是infoo 对象的容器。您可能在 Universe 中单独拥有一个 infoo 对象并对其进行操作。但是,无论如何,如果您必须管理多个,foo 对象就会发挥作用。
即使用户可以实例化一个infoo 对象来播放,代码的目的是让foo 的接口在有多个infoo 时处理。
这是好的做法吗?我是否违反了一些黄金法则?
【问题讨论】:
-
就我个人而言,我不会将代码放在试图神奇地将自身切换为容器类的元素类中。这不是预期的行为。现在我想不出有一次我见过这种情况或希望这种情况发生。你的界面应该以最不令人惊讶的方式做事,否则你会让自己在未来陷入混乱和令人沮丧的调试。
-
非常感谢@Kemp 的回答。事实是,在不获取容器的情况下添加 infoo 对象没有任何意义。没有其他方法可以解释这个类中的 add 运算符,而不是创建容器,没有合并参数,没有参数之间的操作。 foo 类实际上是星座,而 infoo 类是卫星。您可以创建一个卫星并播放,但是当您添加其中两个时,它就会变成一个星座。 Constellation 是一个带有类固醇的容器,可以进行一些转换。
-
您正在构建一个非交换加法运算符。如果
f是foo实例并且i和infoo实例,则f + i将是foo但i + f将是语法错误。如果foo将成为infoo的容器,为什么不从collections.abc的抽象类派生它? -
@ivanculet 如果没有意义,为什么还要实现 add 运算符?您不需要为每个类提供所有可能的运算符。
-
非常感谢@SergeBallesta 的评论。我会调查的。除了编写脚本之外,我将其作为我的第一个大项目来构建,这种类型的评论非常宝贵!再次感谢。
标签: python add magic-methods