【问题标题】:Different return types, overloading __add__不同的返回类型,重载__add__
【发布时间】: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())

如您所见,fooinfoo 对象的容器。您可能在 Universe 中单独拥有一个 infoo 对象并对其进行操作。但是,无论如何,如果您必须管理多个,foo 对象就会发挥作用。

即使用户可以实例化一个infoo 对象来播放,代码的目的是让foo 的接口在有多个infoo 时处理。

这是好的做法吗?我是否违反了一些黄金法则?

【问题讨论】:

  • 就我个人而言,我不会将代码放在试图神奇地将自身切换为容器类的元素类中。这不是预期的行为。现在我想不出有一次我见过这种情况或希望这种情况发生。你的界面应该以最不令人惊讶的方式做事,否则你会让自己在未来陷入混乱和令人沮丧的调试。
  • 非常感谢@Kemp 的回答。事实是,在不获取容器的情况下添加 infoo 对象没有任何意义。没有其他方法可以解释这个类中的 add 运算符,而不是创建容器,没有合并参数,没有参数之间的操作。 foo 类实际上是星座,而 infoo 类是卫星。您可以创建一个卫星并播放,但是当您添加其中两个时,它就会变成一个星座。 Constellation 是一个带有类固醇的容器,可以进行一些转换。
  • 您正在构建一个非交换加法运算符。如果ffoo 实例并且iinfoo 实例,则f + i 将是fooi + f 将是语法错误。如果foo 将成为infoo 的容器,为什么不从collections.abc 的抽象类派生它?
  • @ivanculet 如果没有意义,为什么还要实现 add 运算符?您不需要为每个类提供所有可能的运算符。
  • 非常感谢@SergeBallesta 的评论。我会调查的。除了编写脚本之外,我将其作为我的第一个大项目来构建,这种类型的评论非常宝贵!再次感谢。

标签: python add magic-methods


【解决方案1】:

基本上覆盖在 cmets 中,但这样的设计会更简洁:

class InFoo:
    pass

class Foo:
    def __init__(self, infoos):
        self.args = list(infoos)

    def __add__(self, other):
        if isinstance(other, __class__):
            oargs = other.args
        elif isinstance(other, InFoo):
            oargs = [other]
        return foo(self.args + oargs)

似乎没有任何充分的理由在InFoo 上定义__add__,因为在这种情况下,加法只对容器有意义。这也消除了外部定义infoo_type 的需要。 Python 约定是让类名 CamelCase 和几乎所有其他的蛇形大小写。

【讨论】:

    猜你喜欢
    • 2011-01-27
    • 2010-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-09
    相关资源
    最近更新 更多