我有两个包含一些相同属性块的类。 这些类共享一个共同的祖先,但也有兄弟姐妹没有 需要这些属性。
我不想复制属性代码块。
使用Getter,我的方法是在另一个类中调用权威方法:
# in ConcreteFooz.baz_per_bar:
def baz_per_bar(self):
return ConcreteFoo.baz_per_bar(self)
因为@properties似乎更适合我的需求。 我试过的时候:
# in ConcreteFooz.baz_per_bar:
def baz_per_bar(self):
return ConcreteFoo.baz_per_bar(self)
我回来了:
*** TypeError: 'property' object is not callable
因此;
所以我们通常会参考:
import itertools
class MyBaseClass(object):
pass
class ConcreteFoo(MyBaseClass):
@property
def baz_per_bar(self):
"""Returns as dict of {baz: list bar}"""
# do baz lookup
# do bar lookup
# associcate and return
return my_baz_per_bar
@property
def baz_chain(self):
"""Flattens baz_per_bar into baz's"""
return itertools.chain(*self._baz_chain.values())
class ConcreteFooz(MyBaseClass):
@property
def baz_per_bar(self):
"""Returns as dict of {baz: list bar}"""
# do baz lookup
# do bar lookup
# associcate and return
return my_baz_per_bar
@property
def baz_chain(self):
"""Flattens baz_per_bar into baz's"""
return itertools.chain(*self._baz_chain.values())
class ConcreteJaz(MyBaseClass):
pass
# Does not need property lookup
答案 0 :(得分:2)
我不太确定。 mixin能满足您的需求吗?
import itertools
class MyBaseClass(object):
pass
class BazMixin():
@property
def baz_per_bar(self):
"""Returns as dict of {baz: list bar}"""
# do baz lookup
# do bar lookup
# associcate and return
return my_baz_per_bar
@property
def baz_chain(self):
"""Flattens baz_per_bar into baz's"""
return itertools.chain(*self._baz_chain.values())
class ConcreteFoo(MyBaseClass, BazMixin):
pass
class ConcreteFooz(MyBaseClass, BazMixin):
pass
class ConcreteJaz(MyBaseClass):
pass
# Does not need property lookup
答案 1 :(得分:2)
是的,你可以使用另一个类的属性而不扩展该类。考虑一下这个程序:
import itertools
class MyBaseClass(object):
pass
class ConcreteFoo(MyBaseClass):
def __init__(self):
self.my_baz_per_bar = { 'A' : ['apple', 'aardvark'] }
@property
def baz_per_bar(self):
"""Returns as dict of {baz: list bar}"""
# do baz lookup
# do bar lookup
# associcate and return
return self.my_baz_per_bar
@property
def baz_chain(self):
"""Flattens baz_per_bar into baz's"""
return itertools.chain(*self._baz_chain.values())
class ConcreteFooz(MyBaseClass):
def __init__(self):
self.my_baz_per_bar = { 'Z' : ['zero', 'zebra'] }
baz_per_bar = ConcreteFoo.baz_per_bar
baz_chain = ConcreteFoo.baz_chain
class ConcreteJaz(MyBaseClass):
pass
# Does not need property lookup
print ConcreteFoo().baz_per_bar
print ConcreteFooz().baz_per_bar
或者,考虑这个片段:
@property
def baz_per_bar(self):
return ConcreteFoo.baz_per_bar.fget(self)
请注意,我 修改了您的示例中的ConcreteFoo
,但仅用于修复NameError
。