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
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 elsuper
en lineaInputAssigningMetaclass
¿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
mdeoso
Puede acceder a él por los atributos privados de la clase:
cls_name = self.__class__.__name__
EDITAR:
Como dijo por Ned Batchelder
esto no funcionaría en el cuerpo de la clase, pero sí en un método.
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'
>>>
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__)