Obtener el nombre de la clase actual?

4 minutos de lectura

avatar de usuario
jonathan ginsburg

¿Cómo obtengo el nombre de la clase en la que estoy actualmente?

Ejemplo:

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

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

Debido a la naturaleza del programa con el que estoy interactuando (vistrails), no puedo usar __init__() inicializar input.

obj.__class__.__name__ obtendrá el nombre de cualquier objeto, por lo que puede hacer esto:

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

Uso:

>>> c = Clazz()
>>> c.getName()
'Clazz'

  • ¿Por qué no es esta la respuesta aceptada? EDITAR: Ok, el alcance de OP no es interno, está a nivel de clase.

    – KomodoDave

    10 de noviembre de 2014 a las 12:51


  • @KomodoDave, porque esto está mal, incluso en el alcance del método. Cuando usted llama getName de una clase secundaria generará el nombre de la clase secundaria. Entonces se vuelve complicado si REALMENTE quieres la clase con la que estás trabajando.

    – Kenet Jervet

    8 de junio de 2015 a las 5:16


  • @KenetJervet Te refieres a cuando llamas getName a partir de una padre class, ¿dará salida al nombre de la clase secundaria? Ok Ty por señalar eso.

    – KomodoDave

    8 de junio de 2015 a las 8:06

  • En términos orientados a objetos, la solución (devolver el nombre de la clase secundaria real en tiempo de ejecución incluso si el getName() Sin embargo, el método está definido en una superclase) es correcto.

    – sxc731

    15/10/2016 a las 18:57

avatar de usuario
Ned Batchelder

Dentro del cuerpo de una clase, el nombre de la clase aún no está definido, por lo que no está disponible. ¿No puedes simplemente escribir el nombre de la clase? Tal vez necesite decir más sobre el problema para que podamos encontrar una solución para usted.

Crearía una metaclase para hacer este trabajo por usted. Se invoca en el momento de la creación de la clase (conceptualmente al final de la clase: bloque) y puede manipular la clase que se está creando. No he probado esto:

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'

  • PARA aclarar lo que estoy tratando de hacer: necesito crear e inicializar una variable de clase, ‘entrada’, fuera de un método. Tengo un montón de clases pequeñas, cada una de las cuales debe llamar a ‘get_input’ usando su nombre de clase como parámetro. Estoy tratando de generalizar esto para no tener que ir a cada clase (habrá 100 más o menos) y escribir el nombre de la clase.

    –Jonathan Ginsburg

    4 de agosto de 2011 a las 14:46

  • OK, actualicé mi respuesta con una metaclase que debería ayudar.

    –Ned Batchelder

    4 de agosto de 2011 a las 14:54

  • Que hace MyType en el super en linea InputAssigningMetaclass ¿Referirse a?

    – A.Wan

    1 de diciembre de 2015 a las 22:58

PEP 3155 introducido __qualname__que se implementó en Python 3.3.

Para las funciones y clases de nivel superior, el __qualname__ atributo es igual a __name__ atributo. Para clases anidadas, métodos y funciones anidadas, el __qualname__ El atributo contiene una ruta punteada que conduce al objeto desde el nivel superior del módulo.

Es accesible desde la propia definición de una clase o una función, por ejemplo:

class Foo:
    print(__qualname__)

imprimirá efectivamente Foo. Obtendrá el nombre completo (excluyendo el nombre del módulo), por lo que es posible que desee dividirlo en el . personaje.

Sin embargo, no hay forma de obtener un control real de la clase que se está definiendo.

>>> class Foo:
...     print('Foo' in globals())
... 
False

  • Esta es ahora la mejor respuesta!

    – sourcenouveau

    18 mayo 2021 a las 15:02

avatar de usuario
mdeoso

Puede acceder a él por los atributos privados de la clase:

cls_name = self.__class__.__name__

EDITAR:

Como dijo por Ned Batchelderesto no funcionaría en el cuerpo de la clase, pero sí en un método.

avatar de usuario
Eliminación de negación simple

EDITAR: Sí tu puedes; pero tienes que hacer trampa: el nombre de la clase que se está ejecutando actualmente está presente en la pila de llamadas, y el traceback módulo le permite acceder a la pila.

>>> 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'

Sin embargo, yo no haría esto; Mi respuesta original sigue siendo mi propia preferencia como solución. Respuesta original:

probablemente la solución más simple es usar un decorador, que es similar a la respuesta de Ned que involucra metaclases, pero menos poderosa (los decoradores son capaces de hacer magia negra, pero las metaclases son capaces de antiguo, oculto magia negra)

>>> 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'
>>> 

avatar de usuario
anandhu gopi

@Yuval Adam responde usando @property

class Foo():
    @property
    def name(self):
        return self.__class__.__name__

f = Foo()
f.name  # will give 'Foo'

Creo que debería ser así:

    class foo():
        input = get_input(__qualname__)

¿Ha sido útil esta solución?