Comment puis-je obtenir le nom de la classe dans laquelle je suis actuellement?
Exemple:
def get_input(class_name):
[do things]
return class_name_result
class foo():
input = get_input([class name goes here])
En raison de la nature du programme avec lequel je m'interface (vistrails), je ne peux pas utiliser __init__()
pour initialiser input
.
obj.__class__.__name__
vous donnera n'importe quel nom d'objet, vous pouvez donc faire ceci:
class Clazz():
def getName(self):
return self.__class__.__name__
Usage:
>>> c = Clazz()
>>> c.getName()
'Clazz'
Dans le corps d'une classe, le nom de la classe n'est pas encore défini, il n'est donc pas disponible. Ne pouvez-vous pas simplement taper le nom de la classe? Peut-être devrez-vous en dire plus sur le problème pour que nous puissions trouver une solution à votre problème.
Je créerais une métaclasse pour faire ce travail pour vous. Il est appelé au moment de la création de la classe (conceptuellement à la toute fin de la classe: block) et peut manipuler la classe en cours de création. Je n'ai pas testé ceci:
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'
Vous pouvez y accéder par les attributs privés de la classe:
cls_name = self.__class__.__name__
MODIFIER:
Comme indiqué par Ned Batcheler
, cela ne fonctionnerait pas dans le corps de la classe, mais dans une méthode.
EDIT: Oui, vous pouvez; mais vous devez tricher: le nom de la classe en cours d'exécution est présent sur la pile d'appels et le module traceback
vous permet d'accéder à la pile.
>>> 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'
Cependant, je ne le ferais pas; Ma réponse initiale reste ma propre préférence en tant que solution. Réponse originale:
la solution la plus simple est probablement d'utiliser un décorateur, ce qui est similaire à la réponse de Ned impliquant des métaclasses, mais moins puissant (les décorateurs sont capables de la magie noire, mais les métaclasses sont capables de la ancienne, occulte magie noire).
>>> 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 a introduit __qualname__
, qui a été implémenté dans Python 3.3.
Pour les fonctions et les classes de niveau supérieur, l'attribut
__qualname__
est égal à l'attribut__name__
. Pour les classes, méthodes et fonctions imbriquées imbriquées, l'attribut__qualname__
contient un chemin en pointillé menant à l'objet à partir du niveau supérieur du module.
Il est accessible depuis la définition même d'une classe ou d'une fonction, par exemple:
class Foo:
print(__qualname__)
va effectivement imprimer Foo
. Vous obtiendrez le nom complet (à l’exclusion du nom du module), de sorte que vous voudrez peut-être le scinder en .
.
Cependant, il n'existe aucun moyen d'obtenir un descripteur réel de la classe en cours de définition.
>>> class Foo:
... print('Foo' in globals())
...
False
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()
Je pense que ça devrait être comme ça:
class foo():
input = get_input(__qualname__)