Seite 1 von 1

Klassen nach Variablen durchsuchen

Verfasst: Sonntag 23. Juli 2017, 10:45
von Frostie
Hallo!

Ich habe ein kleines Programm in dem sich mehrere Klassen (auch mit mehreren Unterklassen) mit vielen Variablen (Dictionarys) befinden.

Mein Ziel ist es über Input() einen Namen einzugeben und Python dann alle Klassen durchsucht und schaut ob ein Dictionary diesen Key enthält. Was ich dann brauche ist der Pfad zu diesem Key (also Klasse.Unterklasse.Dictionary...). Am besten in einer Liste falls der Key mehrfach vorhanden ist.

Ein kleines Beispiel:

Code: Alles auswählen

class hallo:
    class test:
        var = {"name": "Frostie", "Lieblingsessen": "Nutella"}
        lalala = {"bahnhof": "test", "nix": "nix"}
    class bahnhof:
        a = {"bowling": "alsdkj"}

class bye:
    f = {"h": "j", "lll": "bbb"}
    class unterklasse:
        class nocheineunterklasse:
            var = {"test": "tach"}
            #Hier sollte "test" gefunden werden

i = input()

#Und hier eine Funktion
durchsuche_klassen_und_variablen_nach_key("test")

#Output: bye.unterklasse.nocheineunterklasse.var
Nach nämlich gefühlt tausenden Versuchen habe ich immer noch nichts hinbekommen ich komme einfach nicht weiter :(

Würde mich auf eure Hilfe freuen!

Mit freundlichen Grüße, Frostie

Re: Klassen nach Variablen durchsuchen

Verfasst: Sonntag 23. Juli 2017, 10:58
von __deets__
Solche Klassenhierarchien sind zwar möglich, aber eigentlich unüblich. Statt Klassen als Datenstrukturen (womöglich auch noch veränderbar) zu missbrauchen solltest du einfach eine Datenstruktur direkt aufbauen. In deinem Fall ein großes Wörterbuch. Kleine hast du ja schon verteilt.

Und dann wird deine Aufgabe ein simples rekursives suchen.

Re: Klassen nach Variablen durchsuchen

Verfasst: Sonntag 23. Juli 2017, 12:30
von BlackJack
@Frostie: Ich würde das ja noch etwas deutlicher formulieren: Das ist absolut unüblich, habe ich so noch nie gesehen und Du hast da auch nur formal gesehen Klassen. Das ist ein totaler Missbrauch von ``class``. Klassen beschreiben eine Klasse von Objekten und dienen als Bauplan für konkrete Exemplare in denen Daten und Funktionen zu Objekten zusammengefasst werden. Nichts davon macht Dein eigenartiges Konstrukt.

Re: Klassen nach Variablen durchsuchen

Verfasst: Sonntag 23. Juli 2017, 14:56
von Frostie
Okay danke Leute dann bau ich das mal um

Re: Klassen nach Variablen durchsuchen

Verfasst: Sonntag 30. Juli 2017, 15:14
von BlackJack
Nicht nachmachen! :-D

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf-8
from __future__ import absolute_import, division, print_function
import inspect


class hallo:
    class test:
        var = {'name': 'Frostie', 'Lieblingsessen': 'Nutella'}
        lalala = {'bahnhof': 'test', 'nix': 'nix'}
    class bahnhof:
        a = {'bowling': 'alsdkj'}
 

class bye:
    f = {'h': 'j', 'lll': 'bbb'}
    class unterklasse:
        class nocheineunterklasse:
            var = {'test': 'tach'}
     

def is_dictionary(obj):
    return isinstance(obj, dict)


def durchsuche_klasse_und_variablen_nach_key(class_, key, path=None):
    if path is None:
        path = list()
    path += [class_.__name__]
    
    for name, mapping in inspect.getmembers(class_, is_dictionary):
        if key in mapping:
            path.append(name)
            return '.'.join(path)

    for _, nested_class in inspect.getmembers(class_, inspect.isclass):
        result = durchsuche_klasse_und_variablen_nach_key(
            nested_class, key, path
        )
        if result is not None:
            return result

    return None


def durchsuche_klassen_und_variablen_nach_key(key):
    module = __import__(__name__)
    for _, class_ in inspect.getmembers(module, inspect.isclass):
        result = durchsuche_klasse_und_variablen_nach_key(class_, key)
        if result:
            return result
    raise KeyError('{0!r} not found'.format(key))


def main():
    # Output: bye.unterklasse.nocheineunterklasse.var
    print(durchsuche_klassen_und_variablen_nach_key('test'))

Re: Klassen nach Variablen durchsuchen

Verfasst: Sonntag 30. Juli 2017, 15:32
von kbr
BlackJack hat geschrieben:Nicht nachmachen!
Wieso? Läuft doch! :)

Jedenfalls mit Python 2. Python 3 wirft einen RecursionError.
Bin da jetzt nicht eingestiegen, vermute aber, dass es an inspect.getmembers() liegt.

EDIT: funktioniert nur mit old style classes.

Re: Klassen nach Variablen durchsuchen

Verfasst: Sonntag 30. Juli 2017, 17:08
von BlackJack
Also bei mir funktioniert es auch mit Python 3. Aber wenn ich in Python 2 von `object` erbe, dann gibt es tatsächlich eine ”Endlosrekursion” weil die Klassen als Attribute `__base__` haben und das hat `__class__` als Attribut was wiederum `__base__` als Attribut hat, was wiederum `__class__` als Attribut hat, …

Dagegen hilft das ausfiltern von Attributen deren Name mit einem Unterstrich beginnen:

Code: Alles auswählen

def durchsuche_klasse_und_variablen_nach_key(class_, key, path=None):
    if path is None:
        path = list()
    path += [class_.__name__]
   
    for name, mapping in inspect.getmembers(class_, is_dictionary):
        if key in mapping:
            path.append(name)
            return '.'.join(path)
 
    for name, nested_class in inspect.getmembers(class_, inspect.isclass):
        if not name.startswith('_'):
            result = durchsuche_klasse_und_variablen_nach_key(
                nested_class, key, path
            )
            if result is not None:
                return result
     
    return None

Re: Klassen nach Variablen durchsuchen

Verfasst: Sonntag 30. Juli 2017, 17:19
von kbr
BlackJack hat geschrieben:Also bei mir funktioniert es auch mit Python 3.
Das finde ich erstaunlich, denn wenn Klassen in Python 2 von object erben, sollten sie sich wie Python 3 Klassen verhalten — new style eben. Bei mir ist das jedenfalls so, d.h. Python 3 hat das Rekursionsproblem, solange dunder-Classes nicht gefiltert werden. Ich habe mit 2.7 und 3.6 getestet.