Existe-t-il une méthode intégrée dans Python pour obtenir un tableau de toutes les variables d'instance d'une classe? Par exemple, si j'ai ce code:
class hi:
def __init__(self):
self.ii = "foo"
self.kk = "bar"
Y a-t-il un moyen pour moi de faire ceci:
>>> mystery_method(hi)
["ii", "kk"]
Edit: Au départ, j'avais demandé des variables de classe par erreur.
Chaque objet a un __dict__
variable contenant toutes les variables et leurs valeurs.
Essaye ça
>>> hi_obj = hi()
>>> hi_obj.__dict__.keys()
Utilisez vars ()
class Foo(object):
def __init__(self):
self.a = 1
self.b = 2
vars(Foo()) #==> {'a': 1, 'b': 2}
vars(Foo()).keys() #==> ['a', 'b']
Vous ne pouvez normalement pas obtenir d'attributs d'instance uniquement avec une classe, du moins pas sans instancier la classe. Vous pouvez cependant obtenir des attributs d'instance pour une instance ou des attributs de classe pour une classe. Voir le module 'inspecter'. Vous ne pouvez pas obtenir une liste d'attributs d'instance, car les instances peuvent vraiment avoir n'importe quoi comme attribut et, comme dans votre exemple, la manière habituelle de les créer consiste simplement à leur assigner la méthode __init__.
Une exception est si votre classe utilise des slots, qui est une liste fixe d'attributs que la classe autorise aux instances. Les slots sont expliqués dans http://www.python.org/2.2.3/descrintro.html , mais il existe divers pièges avec les slots; ils affectent la structure de la mémoire, de sorte que l'héritage multiple peut être problématique, et l'héritage en général doit également prendre en compte les slots.
Les méthodes Vars () et dict fonctionneront pour l'exemple affiché par le PO, mais ne fonctionneront pas pour des objets définis "de manière lâche" tels que:
class foo:
a = 'foo'
b = 'bar'
Pour imprimer tous les attributs non appelables, vous pouvez utiliser la fonction suivante:
def printVars(object):
for i in [v for v in dir(object) if not callable(getattr(object,v))]:
print '\n%s:' % i
exec('print object.%s\n\n') % i
Vous pouvez également tester si un objet a une variable spécifique avec:
>>> hi_obj = hi()
>>> hasattr(hi_obj, "some attribute")
Suggérer
>>> print vars.__doc__
vars([object]) -> dictionary
Without arguments, equivalent to locals().
With an argument, equivalent to object.__dict__.
En d'autres termes, cela enveloppe essentiellement __dict__
Bien qu'il ne s'agisse pas directement d'une réponse à la question OP, il existe un moyen très simple de déterminer quelles variables sont dans la portée d'une fonction. jetez un oeil à ce code:
>>> def f(x, y):
z = x**2 + y**2
sqrt_z = z**.5
return sqrt_z
>>> f.func_code.co_varnames
('x', 'y', 'z', 'sqrt_z')
>>>
L'attribut func_code contient toutes sortes de choses intéressantes. Cela vous permet de faire des trucs sympas. Voici un exemple de la façon dont j'ai utilisé ceci:
def exec_command(self, cmd, msg, sig):
def message(msg):
a = self.link.process(self.link.recieved_message(msg))
self.exec_command(*a)
def error(msg):
self.printer.printInfo(msg)
def set_usrlist(msg):
self.client.connected_users = msg
def chatmessage(msg):
self.printer.printInfo(msg)
if not locals().has_key(cmd): return
cmd = locals()[cmd]
try:
if 'sig' in cmd.func_code.co_varnames and \
'msg' in cmd.func_code.co_varnames:
cmd(msg, sig)
Elif 'msg' in cmd.func_code.co_varnames:
cmd(msg)
else:
cmd()
except Exception, e:
print '\n-----------ERROR-----------'
print 'error: ', e
print 'Error proccessing: ', cmd.__name__
print 'Message: ', msg
print 'Sig: ', sig
print '-----------ERROR-----------\n'
Votre exemple montre "variables d'instance", pas vraiment des variables de classe.
Recherchez dans hi_obj.__class__.__dict__.items()
les variables de classe, ainsi que d'autres membres de la classe tels que les fonctions membres et le module qui les contient.
class Hi( object ):
class_var = ( 23, 'skidoo' ) # class variable
def __init__( self ):
self.ii = "foo" # instance variable
self.jj = "bar"
Les variables de classe sont partagées par toutes les instances de la classe.
construit sur la réponse de dmark pour obtenir ce qui suit, ce qui est utile si vous voulez l'équivalent de sprintf et si tout va bien aider quelqu'un ...
def sprint(object):
result = ''
for i in [v for v in dir(object) if not callable(getattr(object, v)) and v[0] != '_']:
result += '\n%s:' % i + str(getattr(object, i, ''))
return result