我可以在不扩展该类的情况下使用其他类的属性吗?

时间:2015-10-23 20:08:33

标签: python class properties delegates getter

Breif:

我有两个包含一些相同属性块的类。 这些类共享一个共同的祖先,但也有兄弟姐妹没有 需要这些属性。

我不想复制属性代码块。

如果我使用的是Getters:

使用Getter,我的方法是在另一个类中调用权威方法:

# in ConcreteFooz.baz_per_bar:
def baz_per_bar(self):
    return ConcreteFoo.baz_per_bar(self)

但我没有使用getter,

因为@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

2 个答案:

答案 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