Appeler des fonctions Python depuis une chaîne de caractères.
locals()['myfunc'](params) # scope local voir help(locals) globals()['myfunc'](params) # scope global voir help(globals) eval('myfunc')(params)
Dans le cas des appels locals() et globals(), on récupère les symboles dans les dictionnaires respectifs locale et globale et on utilise pour clé le nom de la fonction pour accéder à notre fonction référencée dans le scope adéquat.
def hello(nick): print "Hello, your mail alias is %s@gcu.info" % nick locals()['hello'](lutin) globals()['hello'](lutin) eval('hello')(lutin) OUTPUT: Hello, your mail alias is lutin@gcu.info Hello, your mail alias is lutin@gcu.info Hello, your mail alias is lutin@gcu.info
bar = 42 baz = 'lorem ipsum' quux = [1, 2, 3,] print 'bar=%(bar)d, baz=%(baz)s, quux=%(quux)s' % locals()
OUTPUT:
bar=42, baz=lorem ipsum, quux=[1, 2, 3]
Appeler des méthodes Python et Modifier des attributs depuis une chaîne de caractères.
getattr(instance,'myfunc')(params) setattr(instance, attribute, value) class GCU(object): def __init__(self, nick): self.nick = nick def get_nick(self): return self.nick def set_nick(self, new_nick): self.nick = new_nick g = GCU('lutin') g.get_nick() g.set_nick('lutine') getattr(g, 'get_nick')() setattr(g, 'nick', 'lutin') g.get_nick() OUTPUT: lutin lutine lutin
Quand on utilise un objet ou une lib / whatever qu'on ne connait pas, perso je lis pas trop la doc parce que je suis un flemmeux et plutôt un curieux je fais :
print type(monobjet) <class '__main__.MyClass'>
et la je me dis “ok faut voir plus loin”. La intervient “dir”. dir est un builtin qui retourne un peu tout ce qui forme l'objet qu'on lui balance en paramètre :
print dir(monobjet) '__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__']
et la on a tout plein d'information sur l'objet et c'est un peu la fete.
regardez comme suit et je vous laisse deviner un peu :
chaine = "hello" for attr in dir(chaine): if callable(attr): print "attr %s est une methode de : %s " % (attr, chaine.__class__.__name__) else: print "attr %s est un 'simple' attribut de %s" % (attr, chaine.__class__.__name__)
Tous les objets possèdent un champ __dict__, un dict qui mappe les attributs (mais pas les méthodes, ou les champs par défauts) à leur valeur
class Foo(object): x = 1 y = 2 def __init__(self): self.x = 3 self.z = 4 bar = Foo() print bar.__dict__ bar.__dict__['a'] = 5 print bar.a
OUTPUT:
{'x': 3, 'z': 4} 5
class Foo(object): def bar(self): self.baz = 42 self.quux = [1, 2, 3,] print 'self.baz=%(baz)d, self.quux=%(quux)s' % self.__dict__ Foo().bar()
OUTPUT:
self.baz=42, self.quux=[1, 2, 3]