"""
Ogólny tester lister-mixin: podobny do przeładowywacza tranzytywnego w rozdziale 25., 
ale przekazuje obiekt klasy do testera (nie funkcję), a testByNames dodaje ładowanie zarówno modułu, 
jak i klasy za pomocą ciągów nazw, zgodnie z wzorcem fabryk z rozdziału 31.
"""
import importlib

def tester(listerclass, sept=False):    
    "Przekaż dowolną klasę listującą do listerclass"

    class Super:
        def __init__(self):                 # Klasa nadrzędna __init__
            self.data1 = 'code'             # Utworzenie atrybutów instancji
        def method1(self):
            pass

    class Sub(Super, listerclass):          # Wmieszna method1 i __str__
        def __init__(self):                 # Obiekty listujące mają dostęp do self
            Super.__init__(self)            # Lub super().__init__()
            self.data2 = 'Python'           # Więcej atrybutów instancji
            self.data3 = 3.12
        def method2(self):                  # Zdefiniowanie innej metody
            pass

    instance = Sub()                        # Uwtorzenie intancji z metodą __str__ klasy listującej
    print(instance)                         # Uruchomienie mieszanej metody __str__ (lub poprzez str(x))
    if sept: print(f'\n{'-' * 80}\n')

def testByNames(modname, classname, sept=False):
    modobject   = importlib.import_module(modname)    # Import modułu za pomocą nazwy w postaci łańcucha znaków
    listerclass = getattr(modobject, classname)       # Pobramie atrybutu by za pomocą nazwy w postaci łańcucha znaków
    tester(listerclass, sept)

if __name__ == '__main__':
    testByNames('listinstance',  'ListInstance',  True)      # Test wszystkich trzech
    testByNames('listinherited', 'ListInherited', True)      
    testByNames('listtree',      'ListTree',      False)

