Seite 1 von 1

Nochma eine Frage zu Klassen

Verfasst: Montag 19. Februar 2007, 19:52
von EnTeQuAk
Ich stöbere gerade durchs PythonWiki auf der Suche, nach Ideen für die Weiternentwicklung des dauCMS-Wiki-Syntax-Parsers und bin da auf etwas gestoßen, was mich "anmacht" ;)


[wiki]Meta Klassen[/wiki]

Das sieht irgentwie sehr genial aus... funtkioniert auch...

ABER

Wie kann ich aber bei Klassen, die in die Liste eingetragen werden herausfinden, ob und wenn von welcher Klasse sie irgentetwas Erben?

Das ist etwas, was ich noch nie so richtig verstanden habe... da gibet ja 'super()' -- was ich auch noch net so richtig kapiert habe,... das gibt mir ja die "Oberklasse" zurück.
Aber wie kann ich das von außerhalb aufrufen?

Einfach nur mit 'super' klappts ja net so richtig... :'(

Könnt ihr mir da ein wenig Unter die Arme greifen?

MfG EnTeQuAk

Verfasst: Montag 19. Februar 2007, 20:50
von sape
Hi, EnTe. Ja ich weiß da hilft dir nicht weiter aber möchte es dennoch gesagt haben und außerdem abonniere ich mit dem Post diesen thread ;) :D -- Ich habe das ganze wirkliche Prinzip von Meta Klassen nicht begriffen oder besser gesagt, ich erkenne nicht den Sinn dahinter wofür man sowas benötigt :-[

Ich will mir daher demnächst ein Buch kaufen in dem das beschrieben ist (Hoffentlich auch exakt).

lg

EDIT: *Abo* :)

Verfasst: Montag 19. Februar 2007, 21:13
von rayo
sape hat geschrieben:außerdem abonniere ich mit dem Post diesen thread ;) :D
Du weisst schon dass es dafür einen extra Link gibt?
Ist Links unten auf der Seite und heisst "Bei Antworten zu diesem Thema benachrichtigen".

Bitte benutz den auch und mach nicht sinnlos Posts.

Gruss

Verfasst: Montag 19. Februar 2007, 22:07
von birkenfeld
sape hat geschrieben:Ich habe das ganze wirkliche Prinzip von Meta Klassen nicht begriffen oder besser gesagt, ich erkenne nicht den Sinn dahinter wofür man sowas benötigt :-[
Wenn man das Objektmodell von Python betrachtet -- alles ist ein Objekt -- dann müssen eben auch Klassen Instanzen einer Klasse sein. Das ist die Metaklasse.

Verfasst: Dienstag 20. Februar 2007, 11:52
von EnTeQuAk
vllt. nicht erwähnt --> Mir ging es um das zweite Beispiel ;)

Also um das "zählen" von bestimmten Klassen.


MfG EnTeQuAk

Verfasst: Dienstag 20. Februar 2007, 11:58
von birkenfeld
Magst du nochmal beschreiben, was du eigentlich tun willst? Aus deinem OP werd ich nicht schlau.

Verfasst: Dienstag 20. Februar 2007, 12:39
von EyDu
Wenn ich dich richtig verstanden habe, dann suchst du die Superklassen einer Klasse. Diese bekommst du über das Attribut "__bases__":

Code: Alles auswählen

class A():
    pass

class B():
    pass

class C(A, B):
    pass

bases = C.__bases__
in "bases" befinden sich nun eine Liste von Referenzen auf die Klassen A und B.

EDIT: Dreifache Unterstriche sind einfach falsch...

Verfasst: Dienstag 20. Februar 2007, 14:30
von EnTeQuAk
Magst du nochmal beschreiben, was du eigentlich tun willst? Aus deinem OP werd ich nicht schlau.
Ich möchte meinen Parser erweitern.

So... ich habe mehrere verschiedene (immo 2 ;) ) Token-Typen. Block und Text-Tokens.

Entsprechende Token-Klassen sollen die entprechend definierten Tokens zählen

das siehe hier so aus (ungetestet und nur bsp.haft)

Code: Alles auswählen


class TextToken(type):
    registry = []
    def __new__(cls, name, bases, d):
        new_cls = type.__new__(cls, name, bases, d)
        TextToken.registry.append(new_cls)
        return new_cls

class MyClass(object):
    __metaclass__ = TextToken

class AnotherClass(object):
    __metaclass__ = TextToken
und so weiter...

Das war nur ne Idee... es ginge auch über vererben. Aber da wüsste ich nicht genau, wie das geht. Obiges probiere ich gleich ma aus,.


Also in Kurzform, möchte ich zwei "Hauptklassen", die die verschiedenen Syntax-Klassen "zählen" und ich im Endefekt über diese iterieren kann um verschiedene Aktionen mit denen ausführen zu können.

hoffe, es ist nun etwas klarer formiert...

MFG EnTEQuAk

Verfasst: Dienstag 20. Februar 2007, 14:49
von EnTeQuAk
Oki ;) Obiges funktioniert (vor meinem Post) ;)

Hier das, was ich meinte:

Code: Alles auswählen

class Registry(type):
    registry = []
    def __new__(cls, name, bases, d):
        new_cls = type.__new__(cls, name, bases, d)
        Registry.registry.append(new_cls.__bases__)
        return new_cls

class BlockToken(object):
    def __init__(self):
        self.blck_txt = 'da'

class TextToken(object):
    def __init__(self):
        self.txt = 'dadadada'



class Bold(TextToken):
    __metaclass__ = Registry

class Italic(TextToken):
    __metaclass__ = Registry



class Noparse(BlockToken):
    __metaclass__ = Registry

class List(BlockToken):
    __metaclass__ = Registry

if __name__ == '__main__':
    print Registry.registry
Ist immo nur nen Simples Beispiel.. --> verkörpert aber ganz gut, was ich haben wollte ;)

Vielleicht fällt ja doch noch jemandem anderen etwas "besseres" ein ;)
(sollte es das geben)

MfG EnTeQuAk

Verfasst: Dienstag 20. Februar 2007, 15:09
von N317V
Sorry, OT, aber:
EnTeQuAk hat geschrieben:immo
in my mumble opinion?!

Meiner murmelnden Meinung nach?! :shock: :lol:

Verfasst: Dienstag 20. Februar 2007, 15:14
von EyDu
Willst du Klassen zählen, oder Instanzen von Klassen?

Ach ja, zu immo: http://de.wikipedia.org/wiki/Immo_%28Asteroid%29 :D

Verfasst: Dienstag 20. Februar 2007, 15:34
von birkenfeld
EnTeQuAk hat geschrieben:Oki ;) Obiges funktioniert (vor meinem Post) ;)

Hier das, was ich meinte:

Code: Alles auswählen

class Registry(type):
    registry = []
    def __new__(cls, name, bases, d):
        new_cls = type.__new__(cls, name, bases, d)
        Registry.registry.append(new_cls.__bases__)
        return new_cls

class Bold(TextToken):
    __metaclass__ = Registry

class Italic(TextToken):
    __metaclass__ = Registry

(...)
Ja, jetzt bast du alle Klassen in Registry.registry aufgelistet. Was willst du jetzt mit denen anfangen?

Verfasst: Dienstag 20. Februar 2007, 15:37
von rayo
Hi

Code: Alles auswählen

class Counter(type):
    base_tokens = set()
    def __new__(cls, name, bases, d):
        new_cls = type.__new__(cls, name, bases, d)

        try:
            if Token in bases:
                Counter.base_tokens.add(new_cls)
        except NameError:
            pass
        return new_cls

class Token(object):
    __metaclass__ = Counter

class TextToken(Token):
    pass
class BlockToken(Token):
    pass

class SpecialToken(TextToken):
    pass

print Counter.base_tokens
Listet alle Klassen auch, die von Token direkt vererbt sind.

Gruss

Verfasst: Dienstag 20. Februar 2007, 16:39
von EnTeQuAk
Ja, jetzt bast du alle Klassen in Registry.registry aufgelistet. Was willst du jetzt mit denen anfangen?
Ich möchte (im Enddefekt) erst die BlockTokens verarbeiten (also alle, von BlockToken abgeleiteten Klassen)
und dannach die TextTokens (alle davon abgeleiteten Klassen).

Mehr net... ;)

Ansich funktioniert es ja schon so erstma --> Mir ging es erstma nur um die "Grundstruktur", wie ich die Applikation aufzubauen habe...


MfG EnTeQuAk

Verfasst: Dienstag 20. Februar 2007, 19:29
von BlackJack
Die Frage ist ob man dazu unbedingt Metaklassen braucht oder ob man die nicht auch explizit in der `Registry` anmelden kann.

Insbesondere das bei Deinem Code bei jeder Token-Klasse das `__metaclass__`-Attribut gesetzt werden muss, macht es komplizierter als es sein muss. Bei rayo werden die Unterklassen automatisch registriert, da ist wenigstens ein Gewinn.