编辑:我对边缘案例的看法越多,它看起来就越不实用。我会把它打开,因为我发现它很有趣,但我知道这不是一件好事。
我想拍摄某个类的几个对象,将它们组合成一种多对象'同一个类,它基本上得到子类的相同属性。我不确定如何解释它,所以这是一个例子:
#!/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]
但是,有了这个想法,你必须将列表拆分并输入每个对象的函数调用。
答案 0 :(得分:1)
这是一个有趣的想法!所以下面这个解决方案使用了一个类(Multi
)(因为我们正在创建一个'multi'对象,它应该是一个实际的对象)。我只实现了__getattr__
,但我认为你应该能够根据需要覆盖其他方法(例如。__setattr__
如果要分配,{{1测试相等等等) - 这需要很多计划来确定每个人应该如何行动!
__eq__
我相信你建议的最后一个选项是可能的,但是,除非你使用额外的参数作为标记/切换开关,否则它们不能同时实现。