我可以在不扩展 class 的情况下使用另一个 class 的 属性 吗?

Can I use another class's property without extending that class?

简介:

我有两个 classes,其中包含一些相同的 属性 块对。 这些 classes 有一个共同的祖先,但也有不同的兄弟姐妹 需要这些属性。

我不想复制 属性 代码块。

如果我使用 Getters:

对于Getter,我的方法是调用另一个class中的权威方法:

# 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

所以;

我可以使用另一个 class 的 属性 而不扩展那个 class 吗?


示例代码

所以我们通常指的是:

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

我不太确定。 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

是的,您可以使用另一个 class 的 属性 而无需扩展那个 class。考虑这个程序:

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