[英]How to combine properties defined by different parent classes in python?
Suppose we have two classes and each computes a property stuff
in a different way.假设我们有两个类,每个类stuff
以不同的方式计算属性。 Is is possible to combine their outputs in a method/property of a child class?是否可以将它们的输出组合到子类的方法/属性中?
The following code shows the desired effect (though get_stuff_from
needs to be replaced by a proper python construct, if such thing exists).下面的代码显示了预期的效果(尽管get_stuff_from
需要用适当的 python 结构替换,如果存在的话)。
class Foo():
@property
def stuff(self):
return ['a','b','c']
class Bar():
@property
def stuff(self):
return ['1','2','3']
class FooBar(Foo, Bar):
@property
def stuff(self):
# Computes stuff from the internal state like Foo().stuff
foo_stuff = get_stuff_from(Foo)
# Computes stuff from the internal state like Bar().stuff
bar_stuff = get_stuff_from(Bar)
# Returns the combined results
return foo_stuff + bar_stuff
foo_bar = FooBar()
print(foo_bar.stuff)
which should output:应该输出:
['a', 'b', 'c', '1', '2', '3']
If stuff
were a method instead of a property, this would be simple to implement:如果stuff
是一个方法而不是一个属性,这将很容易实现:
class Foo():
def stuff(self):
return ['a','b','c']
class Bar():
def stuff(self):
return ['1','2','3']
class FooBar(Foo, Bar):
def stuff(self):
# Computes stuff from the internal state like Foo().stuff
foo_stuff = Foo.stuff(self)
# Computes stuff from the internal state like Bar().stuff
bar_stuff = Bar.stuff(self)
# Returns the combined results
return foo_stuff + bar_stuff
foo_bar = FooBar()
print(foo_bar.stuff())
however, I would like to find out whether it is possible to do the same with properties.但是,我想知道是否可以对属性做同样的事情。
A property is just an object with an fget
method.属性只是一个具有fget
方法的对象。 You could access the base class' property object and invoke its fget
method with the self
object that refers to the child class:您可以访问基类的属性对象并使用引用子类的self
对象调用其fget
方法:
class FooBar(Foo, Bar):
@property
def stuff(self):
# Computes stuff from the internal state like Foo().stuff
foo_stuff = Foo.stuff.fget(self)
# Computes stuff from the internal state like Bar().stuff
bar_stuff = Bar.stuff.fget(self)
# Returns the combined results
return foo_stuff + bar_stuff
And now FooBar().stuff
returns ['a', 'b', 'c', '1', '2', '3']
现在FooBar().stuff
返回['a', 'b', 'c', '1', '2', '3']
Having two parents using the same name for two different things is a conflict you should fix before inheriting.让两个父母为两个不同的事物使用相同的名字是一种冲突,您应该在继承之前解决。 Usually, this means using at least one adaptor class.通常,这意味着至少使用一个适配器类。
class Foo():
@property
def stuff(self):
return ['a','b','c']
class Bar():
@property
def stuff(self):
return ['1','2','3']
class BarAdaptor:
def __init__(self):
self.b = Bar()
@property
def bar_stuff(self):
return self.b.stuff
class FooBar(Foo, BarAdaptor):
# Don't repeat or perpetuate the mistake of
# overloading stuff to mean different things.
@property
def foobar_stuff(self):
return self.stuff + self.bar_stuff
For symmetry, you might want to adapt Foo
and Bar
.为了对称,您可能需要调整Foo
和Bar
。
This is inspired by the advice for incorporating non-cooperative classes into a hierarchy of cooperative multiple inheritance classes, outlined in Python's `super() considered super!这是受到将非合作类合并到合作多继承类层次结构中的建议的启发,在Python 的 `super() considered super! . .
You could do it like this, otherwise I don't know why you're deriving from Foo and Bar.你可以这样做,否则我不知道你为什么要从 Foo 和 Bar 派生。 In your current code you were just overwriting these properties.在您当前的代码中,您只是覆盖了这些属性。
class Foo():
@property
def stuff(self):
return self._foo_stuff
@property
def _foo_stuff(self):
return ['a','b','c']
class Bar():
@property
def stuff(self):
return self._bar_stuff
@property
def _bar_stuff(self):
return ['1','2','3']
class FooBar(Foo, Bar):
@property
def stuff(self):
return self._foo_bar_stuff
@property
def _foo_bar_stuff(self):
return self._foo_stuff + self._bar_stuff
foo_bar = FooBar()
print(foo_bar.stuff)
Output:输出:
['a', 'b', 'c', '1', '2', '3']
You can do this using the code below您可以使用以下代码执行此操作
class FooBar(Foo, Bar):
def __init__(self):
self.foo = Foo()
self.bar = Bar()
@property
def stuff(self):
return self.foo.stuff + self.bar.stuff
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.