wake-up-neo.net

Name der aktuellen Klasse erhalten?

Wie bekomme ich den Namen der aktuellen Klasse?

Beispiel:

def get_input(class_name):
    [do things]
    return class_name_result

class foo():
    input = get_input([class name goes here])

Aufgrund der Art des Programms, mit dem ich verbunden bin (Vistrails), kann ich __init__() nicht zum Initialisieren von input verwenden.

78

obj.__class__.__name__ erhält einen beliebigen Objektnamen, so dass Sie dies tun können:

class Clazz():
    def getName(self):
        return self.__class__.__name__

Verwendungszweck:

>>> c = Clazz()
>>> c.getName()
'Clazz'
121
Yuval Adam

Im Hauptteil einer Klasse ist der Klassenname noch nicht definiert und daher nicht verfügbar. Können Sie nicht einfach den Namen der Klasse eingeben? Vielleicht müssen Sie mehr über das Problem sagen, damit wir eine Lösung für Sie finden können.

Ich würde eine Metaklasse erstellen, um diese Arbeit für Sie zu erledigen. Es wird zum Zeitpunkt der Klassenerstellung (konzeptuell am Ende der Klasse: Block) aufgerufen und kann die erstellte Klasse bearbeiten. Ich habe das nicht getestet:

class InputAssigningMetaclass(type):
    def __new__(cls, name, bases, attrs):
        cls.input = get_input(name)
        return super(MyType, cls).__new__(cls, name, bases, newattrs)

class MyBaseFoo(object):
    __metaclass__ = InputAssigningMetaclass

class foo(MyBaseFoo):
    # etc, no need to create 'input'

class foo2(MyBaseFoo):
    # etc, no need to create 'input'
19
Ned Batchelder

Sie können über die privaten Attribute der Klasse darauf zugreifen:

cls_name = self.__class__.__name__

BEARBEITEN:

Wie von Ned Batcheler gesagt, würde dies im Klassenkörper nicht funktionieren, aber in einer Methode.

14
mdeous

EDIT: Ja, Sie können; Sie müssen jedoch schummeln: Der aktuell ausgeführte Klassenname ist auf dem Aufrufstack vorhanden, und das Modul traceback ermöglicht den Zugriff auf den Stack.

>>> import traceback
>>> def get_input(class_name):
...     return class_name.encode('rot13')
... 
>>> class foo(object):
...      _name = traceback.extract_stack()[-1][2]
...     input = get_input(_name)
... 
>>> 
>>> foo.input
'sbb'

Ich würde das jedoch nicht tun. Meine ursprüngliche Antwort ist immer noch meine eigene Lösung als Lösung. Ursprüngliche Antwort:

die wahrscheinlich einfachste Lösung ist die Verwendung eines Dekorators, der der Antwort von Ned mit Metaklassen ähnelt, jedoch weniger stark ist (Dekorateure können schwarze Magie, aber Metaklassen Uralte, Okkulte Schwarze Magie.

>>> def get_input(class_name):
...     return class_name.encode('rot13')
... 
>>> def inputize(cls):
...     cls.input = get_input(cls.__name__)
...     return cls
... 
>>> @inputize
... class foo(object):
...     pass
... 
>>> foo.input
'sbb'
>>> 

PEP 3155 Einführung von __qualname__, das in Python 3.3 implementiert wurde.

Für Funktionen und Klassen der obersten Ebene entspricht das __qualname__-Attribut dem __name__-Attribut. Bei verschachtelten Klassen, Methoden und verschachtelten Funktionen enthält das __qualname__-Attribut einen gepunkteten Pfad, der von der obersten Ebene des Moduls zum Objekt führt.

Es ist von der Definition einer Klasse oder einer Funktion aus zugänglich, so zum Beispiel:

class Foo:
    print(__qualname__)

wird Foo..__ effektiv drucken. Sie erhalten den vollständig qualifizierten Namen (mit Ausnahme des Modulnamens), so dass Sie ihn nach dem .-Zeichen aufteilen möchten.

Es gibt jedoch keine Möglichkeit, die Klasse, die definiert wird, wirklich in den Griff zu bekommen.

>>> class Foo:
...     print('Foo' in globals())
... 
False
2
Right leg
import sys

def class_meta(frame):
    class_context = '__module__' in frame.f_locals
    assert class_context, 'Frame is not a class context'

    module_name = frame.f_locals['__module__']
    class_name = frame.f_code.co_name
    return module_name, class_name

def print_class_path():
    print('%s.%s' % class_meta(sys._getframe(1)))

class MyClass(object):
    print_class_path()
1
Pavel Patrin

Ich denke, es sollte so sein:

    class foo():
        input = get_input(__qualname__)
0
Shtefan