如何拥有一个" multi"类或对象的对象处理程序?

时间:2017-06-12 02:29:19

标签: python-3.x oop

编辑:我对边缘案例的看法越多,它看起来就越不实用。我会把它打开,因为我发现它很有趣,但我知道这不是一件好事。

我想拍摄某个类的几个对象,将它们组合成一种多对象'同一个类,它基本上得到子类的相同属性。我不确定如何解释它,所以这是一个例子:

#!/usr/bin/env python3

class Foo:
    def __init__(self, x):
        self.x = x

    def bar(self, y):
        print(self.x)
        return 2 * y


f1 = Foo(2)
f2 = Foo(3)
f3 = Foo(5)
f4 = Foo(7)

def multi(*args):
    if len(args) == 0:
        raise ValueError("Requires at least one object")
    if not all(isinstance(arg, type(args[0])) for arg in args):
        raise TypeError("All objects must be the same type")
    # ... magic

multi_f = multi(f1, f2, f3, f4)

assert multi_f.x == [2, 3, 5, 7]  # attributes return a list of each of the objects in the multi_f
assert multi_f.bar(y=5) == [10, 10, 10, 10]  #  prints 2 then 3 then 5 then 7 but "5" is passed to all of them

我最初虽然压倒了__getattr__和朋友,但想到了所有其他功能,你必须覆盖并想知道是否有更好的方法。

bar函数的另一个替代方案是每个函数都可以获得它自己的参数,但这些参数是互斥的:

assert multi_f.bar([
    [[], dict(y=5)],
    [[], dict(y=10)],
    [[], dict(y=20)],
    [[], dict(y=40)],
]) == [10, 20, 40, 80]

但是,有了这个想法,你必须将列表拆分并输入每个对象的函数调用。

1 个答案:

答案 0 :(得分:1)

这是一个有趣的想法!所以下面这个解决方案使用了一个类(Multi)(因为我们正在创建一个'multi'对象,它应该是一个实际的对象)。我只实现了__getattr__,但我认为你应该能够根据需要覆盖其他方法(例如。__setattr__如果要分配,{{1测试相等等等) - 这需要很多计划来确定每个人应该如何行动!

__eq__

我相信你建议的最后一个选项是可能的,但是,除非你使用额外的参数作为标记/切换开关,否则它们不能同时实现。