简体   繁体   中英

python object building using multi-inheritance

I want to build an object dynamically which allow use to mix the class properties in whichever way they like base on multiple inheritance. This is the expected behaviour. These classes are dataclasses so there won't be many methods in them, mostly data properties.

class Foo():
    def bar(self, x):
            return x

class FooA(Foo):
    def bar(self, x):
        p = super().bar(x)
        p += __class__.__name__
        return p

class FooB(Foo):
    def bar(self, x):
        p = super().bar(x)
        p += __class__.__name__
        return p

class FooC(FooA, FooB):
    def bar(self, x):
        p = super().bar(x)
        p += __class__.__name__
        return p

f = FooC()
f.bar('S') # SFooBFooAFooC

However this code violate the DRY principle in broad daylight, hence I want to avoid the bar method completely, if there is no special operations in the current class.

Ideally I want something like

@bar_wrapper
class FooA(Foo):
    pass

# OR

class FooA(Foo):
    __metaclass__ = BarBase

Instead of this full implementation

class FooA(Foo):
    def bar(self, x):
        p = super().bar(x)
        p += __class__.__name__
        return p

Essentially is there a way that I extract the middle layer class information in a multi-level inheritance class through a decorator or metaclass (the two options that I can think of)? Anyone has any idea on how to do this?

Write a class decorator that adds the bar method to the class:

def bar_wrapper(cls):
    def bar(self, x):
        p = super(cls, self).bar(x)
        p += cls.__name__
        return p

    bar.__module__ = cls.__module__
    bar.__qualname__ = '{}.{}'.format(cls.__qualname__, bar.__name__)

    cls.bar = bar
    return cls

class Foo():
    def bar(self, x):
        return x

@bar_wrapper
class FooA(Foo):
    pass

@bar_wrapper
class FooB(Foo):
    pass

@bar_wrapper
class FooC(FooA, FooB):
    pass

f = FooC()
print(f.bar('S')) # SFooBFooAFooC

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM