euh appel de fonctions à partir d' une liste ou d' un dictionnaire ??

euh appel de fonctions à partir d' une liste ou d' un dictionnaire ?? - Python - Programmation

Marsh Posté le 12-06-2004 à 22:31:50    

Bonsoir
 
Je programmes un bot IRC, et j' ai une liste contenant toutes les commandes possibles.
 

Code :
  1. commands_global=[
  2. '!op',      'identify',  'say',      '!resolv',...]


 
si le premier mot du message envoyé par un utilisateur fait parti de cette liste, alors j' appelle une fonction qui va faire une suite de 'if, elif' jusqu a trouvé la bonne commande.
 

Code :
  1. if self.words[0] in commands_global:
  2.             self.command()


 

Code :
  1. def command(self):
  2.          if self.words[0]== '!op':
  3.              blablabla...
  4.          elif self.words[0]=='identify':
  5.              blablabla


 
j' aimerais plutot créer une fonction ne retournant rien pour chaque commande, mais je ne sais pas comment les appeller sans la suite de if.
si quelqu un peut m aider merci d avance.


Message édité par Profil supprimé le 12-06-2004 à 23:15:50
Reply

Marsh Posté le 12-06-2004 à 22:31:50   

Reply

Marsh Posté le 12-06-2004 à 23:55:12    

Tu peux faire un dictionnaire de fonctions

Reply

Marsh Posté le 13-06-2004 à 08:28:26    

bonjour
 

Ekxon a écrit :

Bonsoir

Code :
  1. if self.words[0] in commands_global:
  2.     self.command()
  3. def command(self):
  4.     if self.words[0]== '!op':
  5.         blablabla...
  6.     elif self.words[0]=='identify':
  7.         blablabla




 
après ton test if, tu peux utiliser la methode apply(self.words[0], arguments), avant il faut avoir créé une fonction par commande.
 
le_GLu


---------------
Python facile : http://pythonfacile.free.fr/ Les ressources (liens) en français sur Python.
Reply

Marsh Posté le 13-06-2004 à 09:42:57    

apply(self.words[0], arguments)
 
:o
 
self.words[0](*arguments) :o

Reply

Marsh Posté le 13-06-2004 à 13:13:29    

bha du coup j' ai fait un dictionnaire de fonctions

Code :
  1. class IRC:
  2.                                                                                        
  3.     def __init__(self):
  4.         self.cmd    = '!deop'
  5.                                                                                                
  6.     def op(self):
  7.         print 'op'
  8.                                                                                        
  9.     def deop(self):
  10.         print 'deop'
  11.                                                                                        
  12.     def test(self):
  13.         self.dico = { 'op': self.op, '!deop': self.deop}
  14.         if self.cmd in self.dico.keys():
  15.             self.dico[self.cmd]()
  16.                                                                                        
  17. a = IRC()
  18. a.test()


 
j' ai environ 50 commandes, c' est quand meme mieux que la longue suite de if, elif non ?
merci

Reply

Marsh Posté le 14-06-2004 à 09:14:23    

Tu peux meme utiliser getattr ici.
 
Je ne suis un caid d'IRC (j'y connais a peu pres rien en fait), mais si je me souviens bien les commandes commencent soit par rien soit par '!'.
 
Imaginons que les commandes soient entrees dans une chaine "command"
 
tu peux faire un truc du style
 

Code :
  1. def ApplyCommand(self, command)
  2.     getattr(self,command.strip('!'))


 
Avec ca, si command == "!op" getattr va appeler self.op(), si command == "identify" getattr va appeler self.identify(), ...

Reply

Marsh Posté le 14-06-2004 à 09:41:31    

Masklinn a écrit :

Tu peux meme utiliser getattr ici.
 
Je ne suis un caid d'IRC (j'y connais a peu pres rien en fait), mais si je me souviens bien les commandes commencent soit par rien soit par '!'.
 
Imaginons que les commandes soient entrees dans une chaine "command"
 
tu peux faire un truc du style
 

Code :
  1. def ApplyCommand(self, command)
  2.     getattr(self,command.strip('!'))


 
Avec ca, si command == "!op" getattr va appeler self.op(), si command == "identify" getattr va appeler self.identify(), ...


 
Ne l'ecoute pas ! On n'a pas le droit au buffer overrun en Python ce n'est pas pour aller coder une autre catégorie de trou de sécurité. Le dictionnaire de fonctions c'est très bien.

Reply

Marsh Posté le 14-06-2004 à 14:21:43    

Kristoph a écrit :

Ne l'ecoute pas ! On n'a pas le droit au buffer overrun en Python ce n'est pas pour aller coder une autre catégorie de trou de sécurité. Le dictionnaire de fonctions c'est très bien.


?
qu'est ce que t'as contre getattr?  :cry:
en plus ca permet de faciliter la gestion d'erreurs et l'ajout de commandes gerees avec getattr  :sweat:


Message édité par masklinn le 14-06-2004 à 14:24:23
Reply

Marsh Posté le 14-06-2004 à 15:38:19    

Masklinn a écrit :

?
qu'est ce que t'as contre getattr?  :cry:
en plus ca permet de faciliter la gestion d'erreurs et l'ajout de commandes gerees avec getattr  :sweat:


 
Et pourquoi pas un exec des commandes IRC du premier venu aussi ? Je n'ai rien de particulier contre getattr sauf quand les paramètres de celui-ci sont directement fournis par un utilisateur sans aucune autre validation.

Reply

Marsh Posté le 15-06-2004 à 14:21:26    

Kristoph a écrit :

Et pourquoi pas un exec des commandes IRC du premier venu aussi ? Je n'ai rien de particulier contre getattr sauf quand les paramètres de celui-ci sont directement fournis par un utilisateur sans aucune autre validation.


getattr n'empeche pas de faire des verifications en amont (avant d'executer la fonction a coup de getattr) ou apres (dans la fonction appelee par getattr) sachant que toute commande pour laquelle on a pas cree de fonction va lancer une exception ou une fonction par defaut (3e membre de getattr, optionnel)

Reply

Marsh Posté le 15-06-2004 à 14:21:26   

Reply

Marsh Posté le 15-06-2004 à 15:18:10    

Ca ne sert donc à rien de faire à la fois un test de validation sur les commandes suivi d'un getattr. Met toutes les commandes possibles dans un dico et basta. Le test de validation et le get se font en une seule operation comme ça. Cela évite de dupliquer de l'information inutilement ce qui est très souvent une source d'erreurs.

Reply

Marsh Posté le 15-06-2004 à 16:17:46    

__getattribute__ :o

Reply

Marsh Posté le 15-06-2004 à 17:59:22    

Kristoph a écrit :

Ca ne sert donc à rien de faire à la fois un test de validation sur les commandes suivi d'un getattr. Met toutes les commandes possibles dans un dico et basta. Le test de validation et le get se font en une seule operation comme ça. Cela évite de dupliquer de l'information inutilement ce qui est très souvent une source d'erreurs.


j'ai un peu de mal la...
 
avec ma solution, t'es pas oblige de faire des tests, il te suffit de creer une fonction pour chaque commande possible puis une fonction "defaut"' (qui peut etre vide) executee en cas de commande impossible/non authorisee/non geree
 
Ni plus ni moins de tests qu'avec un dico mais des donnees en moins vu qu'on se passe du dictionnaire -_-

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed