appel d'une méthode avec une chaine
Le
Jonathan Barnoud
Bonjour
C'est les vacances et j'essaie de programmer un jeu en réseau.
J'aimerais que mes client s'envoient des chaines du style : "METHODE objet
param1,param2" et que cela puisse amener les autres clients à appeller quelque chose
du genre :
items["objet"].METHODE(param1, param2)
sachant bien sur que l'objet items["objet"] existe et a une méthode METHODE qui prend
param1 et param2 comme paramètre mais que la requête à la base ("METHODE objet
param1,param2") est une chaine.
Question auxiliaure : est-il possible pour ma méthode METHODE de modifier self.param1
par exemple ? ou dois-je obligatoirement passer par un dictionnaire ?
Bien sur, si vous avez une idée sur une autre façon de faire je suis preneur
(parceque là je patauge un peu)
Jonathan Barnoud (qui espère être compréhensible et même mieu compri)
C'est les vacances et j'essaie de programmer un jeu en réseau.
J'aimerais que mes client s'envoient des chaines du style : "METHODE objet
param1,param2" et que cela puisse amener les autres clients à appeller quelque chose
du genre :
items["objet"].METHODE(param1, param2)
sachant bien sur que l'objet items["objet"] existe et a une méthode METHODE qui prend
param1 et param2 comme paramètre mais que la requête à la base ("METHODE objet
param1,param2") est une chaine.
Question auxiliaure : est-il possible pour ma méthode METHODE de modifier self.param1
par exemple ? ou dois-je obligatoirement passer par un dictionnaire ?
Bien sur, si vous avez une idée sur une autre façon de faire je suis preneur
(parceque là je patauge un peu)
Jonathan Barnoud (qui espère être compréhensible et même mieu compri)

Poser une question


J'essaierais peut-être de parser le message et d'utiliser getattr :
########
def appelle_vite(message):
methode, objet, params = message.split(' ')
args = params.split(',')
getattr(objets[objet], methode)(*args)
########
ou en faisant plus gaffe aux erreurs potentielles :
########
def appelle(message):
try:
methode, objet, params = message.split(' ')
except ValueError:
print 'Message "%s" incorrect.'%message
return
args = params.split(',')
try:
getattr(objets[objet], methode)(*args)
except KeyError:
print 'Objet %s inconnu.'%objet
except AttributeError:
print 'Methode %s inconnue.'%methode
except TypeError:
print 'Argument(s) incorrect(s).'
########
On peut tester avec :
########
class A(object):
def __init__(self, nom):
self.nom = nom
def m1(self, *args):
print 'm1 de %s appele avec : '%self.nom + ', '.join(args)
def m2(self, p1, p2):
print 'm2 de %s appele avec p1=%s et p2=%s.'%(self.nom, p1, p2)
a1 = A('a1')
a2 = A('a2')
objets = {'a1': a1, 'a2': a2}
appelle('m2 a1 a,b')
appelle('m2 a2 a,b')
appelle('m1 a1 ') # pas d'argument
appelle('m1 a3 ') # l'objet n'existe pas
appelle('m3 a1 ') # la methode n'existe pas
appelle('m1 a1') # le split va echouer
appelle('m2 a1 1') # pas assez d'arguments
appelle('m1 a1 1,2 , 0.1') # le premier split va echouer
########
Ca donne :
m2 de a1 appele avec p1=a et p2=b.
m2 de a2 appele avec p1=a et p2=b.
m1 de a1 appele avec :
Objet a3 inconnu.
Methode m3 inconnue.
Message "m1 a1" incorrect.
Argument(s) incorrect(s).
Message "m1 a1 1,2 , 0.1" incorrect.
Voila. C'est encore loin d'être parfait, en particulier du côté de
l'analyse du message (il faut faire attention aux arguments par exemple)
mais peut-être que ça vous aidera.
Oui. Modifier des membres d'un objet est une des choses courantes faites
dans ses méthodes.
Mais la question porte peut-être sur param1 (au lieu de self.param1)
auquel cas la réponse générale est oui (en utilisant les méthodes de
param1 qui le permettent s'il y en a).
Ou alors je suis passé à côté de la question (mais certains ne sont pas
en vacances et ont l'excuse d'être fatigués après une journée de travail
;)).
L'idée aurait été de pouvoir faire quelque chose du genre :
class Test:
def __init__(self):
self.test = "test"
self.getattr("test") = "test2"
toto = Test() #qui afficherait "test2"
En effet, j'ai une méthode qui modifie l'une des caractéristique de mon personnage,
elle prend le nom de la caractéristique et la modification en paramètre.
def alter(key, val):
try :
self.vals[key] += int(val)
except KeyError :
print "La clé %s n'esiste pas." % key
et j'aurais voulu utiliser self.key plutôt que self.vals["key"].
Jonathan Barnoud
Merci c'eSt exactement ce que je cherchais. Je vais pouvoir avancER maintenant.
Raaa ces jeunes ! Ils savent même plus écrire !!
Jonathan Barnoud
Attention, getattr n'est pas /a priori/ une methode de ta classe ; il
s'agit d'un builtin [1]. De plus il renvoie la valeur (l'objet) donc il
ne se modifie pas ainsi.
Ton affectation s'ecrirait plutot (en plus de self.test = 'test2'):
setattr(self, 'test', 'test2')
Le probleme de self.key est qu'il cherche un membre de nom 'key'. Il
faudrait lui dire que le nom est key et non pas 'key'. C'est le but des
(get|set|del)attr.
Par contre, tu peux aussi utiliser le dictionnaire des membres d'un
objet : __dict__ [2] plutot que d'en creer un autre.
Si tu veux pouvoir utiliser a.test et a.alter('test', val), tu peux
alors ecrire au choix (sans oublier de passer self a alter ;)) :
########
class A(object):
def alter(self, key, val):
try:
setattr(self, key, getattr(self, key) + val)
except AttributeError:
print "La cle %s n'existe pas"%key
def alter2(self, key, val):
try:
self.__dict__[key] += val
except KeyError:
print "La cle %s n'existe pas"%key
########
A l'utilisation on a bien :
Voila, j'espere que j'ai bien compris le probleme. :)
[1] http://docs.python.org/lib/built-in-funcs.html
[2] http://docs.python.org/lib/specialattrs.html
Merci beaucoup. Je vais pouvoir faire de beaux objets maintenant plutôt que les trucs
bancaux que je faisait jusqu'à présent.
Et puis il va faloir que je prennent le temps d'apprendre à lire avant de poser ma
prochaine question :)
Jonathan Barnoud