[Python] How to "collect" all items associated with a chain of superclasses?

Discussão em 'Python' iniciado por Stack, Fevereiro 16, 2025.

  1. Stack

    Stack Membro Participativo

    Problem

    Let's say I have a hierarchy of classes where each class has an associated list of class-specific items, e.g.

    class Thing:
    Items = ['Exist']

    class Being(Thing):
    Items = ['Live', 'Die']

    class Human(Being):
    Items = ['Read' 'Write']


    I'd like to define a function GetAllItems() that for any class in the hierarchy, will return its own items and those of its superclasses, i.e:

    Thing.GetAllItems() # ==> ['Exist']
    Being.GetAllItems() # ==> ['Live', 'Die', 'Exist']
    Human.GetAllItems() # ==> ['Read', 'Write', 'Live', 'Die', 'Exist']


    It doesn't have to be static methods, but after all, the items that I want to be able to "accumulate" are fundamentally Class-level properties.

    What I tried

    I was thinking that I could write some kind of simple recursive function, along the lines of:

    class A:
    Items = [A1, A2, A3]

    def GetAllItems(): # not sure how to do this for a static method
    return getattr(type(self),'Items') + super().GetAllItems()


    and then have this function work in all the derived classes, i.e. B(A), C(B), etc, but that doesn't really work.

    The closest I got was to specify a different Items variable in each class, and then provide the (non-static) GetAllItems() function for each class like so:

    class A:
    ItemsA = [A1, A2, A3]

    def GetAllItems():
    return A.ItemsA # this is the "root" function

    class B(A):
    ItemsB = [B1, B2, B3]

    def GetAllItems():
    return B.ItemsB + super().GetAllItems()

    class C(B):
    ItemsC = [C1, C2, C3]

    def GetAllItems():
    return C.ItemsC + super().GetAllItems()


    While it's not the end of the world to add a function like this to each derived class, I do have a lot of classes, and it would be nice to be able to do this with a single piece of code somehow without copying and pasting basically the same thing everywhere... Plus I still don't fully understand how super() works, so I feel like there's maybe a more elegant solution to this.

    Continue reading...

Compartilhe esta Página