Seite 1 von 1

Klassenname vom Aufruf herrausfinden...

Verfasst: Dienstag 7. Juni 2005, 17:20
von jens
(Hatte ich danach schon einmal gefragt?)

Ist es möglich herrauszufinden, von welcher Klasse eine Methode aufgerufen wird???
Das wäre für eine automatische LOG-Kategorie gut.

Hier mal Pseudocode:

Code: Alles auswählen

class log:
    def __call__( self, msg ):
        KATEGORIE = tollefunktiondiedenklassennamenherrausfindet()
        file.write( KATEGORIE + msg )

class login:
    def __init__( self, log_class ):
        self.log = log_class
    def checkUser():
        if Username != db_Username:
            self.log("Fehler!!!")

class editor:
    def __init__( self, log_class ):
        self.log = log_class
    def edit( filename ):
        self.log("Edit File" + filename)

class programm:
    def __init__( self ):
        self.log = log()
        editor = editor( self.log )
        login = login( self.log )
        
        if login.checkUser() == True:
            editor.edit( "wichtigebeispieldatei.txt" )
Also ich möchte in der Klasse log() bei __call__() wissen, wie die Klasse heißt, von der aus die Methode aufgerufen wurde. Also in dem Falle entweder "login" oder "editor"...

Ansonsten muß ich in jeder Datei einen String mit der Kategorie setzten und den immer mit übergeben... Oder noch eine andere Lösung?

Verfasst: Mittwoch 8. Juni 2005, 00:17
von BlackJack
Wenn Du Dich auf CPython beschränkst und davon ausgehen kannst, das der erste Parameter einer Methode immer `self` heisst und die `log`-Methode nur von Methoden und nicht Funktionen aufgerufen wird, dann geht das grundsätzlich schon. Ich würde aber dringend davon abraten.

Code: Alles auswählen

import inspect

def log(msg):
    print inspect.stack()[1][0].f_locals['self'].__class__.__name__
    print msg

class A:
    def spam(self):
        log('eggs')

A().spam()

Verfasst: Mittwoch 8. Juni 2005, 08:48
von jens
Ich sehe schon, das ist recht unfein :)
Ich kann schon davon außgehen das es nur für CPython ist (würde als CGI laufen). Allerdings kann ich nicht unbedingt garantieren, das es immer aus Methoden aufgerufen wird. Man kann das ganze ja auch mit try versuchen...

Welche Nachteile sind damit noch verbunden???


Hier eine Ausführlichere Version:

Code: Alles auswählen

import inspect

class log:
    def __call__( self, msg ):
        filename    = inspect.stack()[1][1]
        methodname  = inspect.stack()[1][3]
        try:
            classname = inspect.stack()[1][0].f_locals['self'].__class__.__name__
        except KeyError:
            classname = "?"

        print "%s %s.%s - %s" % (filename,classname,methodname,msg)

class login:
    def __init__( self, log_class ):
        self.log = log_class
    def checkUser( self ):
        self.log("checke User!")

class editor:
    def __init__( self, log_class ):
        self.log = log_class
    def edit( self, filename ):
        self.log("Edit File" + filename)

class programm:
    def __init__( self ):
        self.log = log
        e = editor( self.log )
        l = login( self.log )

        l.checkUser()
        e.edit( "wichtigebeispieldatei.txt" )

log = log()
log("Starte Programm")
programm()
Liefert:
test.py ?.? - Starte Programm
test.py login.checkUser - checke User!
test.py editor.edit - Edit Filewichtigebeispieldatei.txt