Partage
  • Partager sur Facebook
  • Partager sur Twitter

Commande

decorateur

    21 décembre 2011 à 10:57:49

    Bonjour, j'ai un petit problème avec les décorateur. L'erreur est peut être toute bête mais je ne trouve pas la solution. Quand j'essaie ce script :
    def servcommand(nom_court,description):
        def decorator(function):
            return function
        return decorator
    
    @servcommand("test", "Affiche Bravo")
    def test():
        print "Bravo"
    
    Il m'affiche : <function test at 0x01FA1330>
    J'ai regarder dans le tutoriel mais je n'est pas trouver la solution ><
    Merci d'avance !
    • Partager sur Facebook
    • Partager sur Twitter
      21 décembre 2011 à 11:04:14

      Il est censé servir à quoi ton décorateur ?

      Parce que là le comportement de ton décorateur est juste normal : il ne fait strictement rien et retourne la fonction telle quelle.

      PS :

      @servcommand("test", "Affiche Bravo")
      def test():
          print "Bravo"
      
      # est équivalent à
      
      def test():
          print "Bravo"
      test = servcommand("test", "Affiche Bravo")(test)
      
      # est équivalent à 
      
      test = (def decorator(function): return function)(test)
      
      # est équivalent à 
      
      test = decorator(test)
      
      # est équivalent à 
      
      test = test
      
      • Partager sur Facebook
      • Partager sur Twitter
      Zeste de Savoir, le site qui en a dans le citron !
        21 décembre 2011 à 11:09:17

        Le but est de créer un client pour un serveur tout simple qui sera contrôler en ligne de commande comme pour les serveurs craftbukkit de Minecraft.

        • Partager sur Facebook
        • Partager sur Twitter
          21 décembre 2011 à 11:14:28

          Non mais je veux dire : quel est le comportement attendu de ton décorateur ?
          • Partager sur Facebook
          • Partager sur Twitter
          Zeste de Savoir, le site qui en a dans le citron !
            21 décembre 2011 à 11:36:03

            Je ne comprend pas ta question mais je vais essayer de te répondre quand même.
            j'attend que mon décorateur test affiche bravo.
            • Partager sur Facebook
            • Partager sur Twitter
              21 décembre 2011 à 11:45:42

              Citation : Beydamo

              Je ne comprend pas ta question mais je vais essayer de te répondre quand même.
              j'attend que mon décorateur test affiche bravo.



              Bon, y'a pas, je n'arrive pas à comprendre ce que tu cherches à faire ni quel est ton problème.

              Qu'est-ce qui ne fonctionne pas précisément dans ton décorateur ?

              Donne-nous un exemple d'entrée et de sortie, montre-nous du code qui nous permettrait de comprendre ce que tu veux faire. C'est ce que tu aurais dû faire dès le début de ce topic.
              • Partager sur Facebook
              • Partager sur Twitter
              Zeste de Savoir, le site qui en a dans le citron !
              Anonyme
                21 décembre 2011 à 11:48:37

                Citation

                j'attend que mon décorateur test affiche bravo.



                Ta fonction test affiche déjà bravo, intérêt du déco?

                Sinon si tu insistes dans cette idée inutile, voilà la bonne syntaxe

                def servcommand(func):
                    return func
                
                @servcommand
                def test():
                    print('Bravo') # print 'Bravo' pour la version 2.x
                
                • Partager sur Facebook
                • Partager sur Twitter
                  21 décembre 2011 à 11:57:17

                  Ok, je vais recommencer.

                  Mon but et de creer un client pour un serveur basique.

                  Voici le code du serveur :
                  # -*- coding: cp1252 -*-
                  import socket
                  
                  hote = ''
                  port = 12800
                  
                  connexion_principale = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                  connexion_principale.bind((hote, port))
                  connexion_principale.listen(5)
                  print("Le serveur écoute à présent sur le port {}".format(port))
                  
                  connexion_avec_client, infos_connexion = connexion_principale.accept()
                  
                  msg_recu = b""
                  while msg_recu != b"fin":
                      msg_recu = connexion_avec_client.recv(1024)
                      # L'instruction ci-dessous peut lever une exception si le message
                      # réceptionné comporte des accents
                      print(msg_recu.decode())
                      connexion_avec_client.send(b"5 / 5")
                  
                  print("Fermetures de connexions")
                  connexion_avec_client.close()
                  connexion_principale.close()
                  


                  Je voudrait que mon client marche grâce à des commande pour se connecter et se déconnecter du serveur. (Plus tard j’essaierais de l'améliorer pour voir le nombre de personne connecter au serveur, ... )

                  j'aimerais faire un script ressemblant à celui ci :

                  import ftplib as ftp # on importe le module et on la renomme juste pour le script en "ftp"
                   
                  commands = {} # on crée le dictionnaire qui contiendra toutes les commandes &amp; descriptions
                   
                  def connection(value=None):
                      if value == None:
                          return getattr(connection, 'value', None)
                      else:
                          connection.value = value
                          return value
                   
                  def ftpcommand(nom_court, description): # fonction pour ajouter la fonction au dictionnaire commands
                      def decorator(function):
                          global commands # on n'oublie pas de mettre le dico commands global, sinon ça va en redéfinir un
                          commands[nom_court] = (function, description) # on ajoute au dictionnaire
                          return function
                      return decorator
                   
                  @ftpcommand("help", "Affiche l'aide des commandes") # ici on appelle le décorateur : il va s'occuper d'ajouter la fonction help avec sa description au dictionnaire commands
                  def help(): # définition de la commande, juste après @ftpcommand car ON EST OBLIGÉS
                      global commands
                      keys = commands.keys() # on récupère les clés == fonctions dans notre cas
                      keys.sort() # on trie par ordre alphabétique 
                      for i in keys:
                          print i+" : "+commands[i][1] # on affiche le nom de la fonction et sa description
                   
                  @ftpcommand("connect", "Se connecte au serveur. Syntaxe: connect <host> <user> <password>")
                  def connect(host, user, password):
                      connection(ftp.FTP(host, user, password))
                   
                  @ftpcommand("ls", "Liste le contenu du répertoire actuel")
                  def ls():
                      print connection().dir() # on affiche le listing du répertoire
                   
                  @ftpcommand("deco", "Se déconnecte du serveur. Syntaxe: deco")
                  def deco():
                          connection().quit() # la déconnexion avec quit()
                   
                  @ftpcommand("envoi", "Envoie un fichier au serveur. Syntaxe: envoi <adresse_fichier>")
                  def envoi(adresse_fichier):
                        fichier = adresse_fichier
                        file = open(fichier, 'rb') # on ouvre le fichier en mode "read-binary"
                        connection().storbinary('STOR '+fichier, file) # envoi
                        file.close() # fermeture du fichier
                   
                  @ftpcommand("rename", "Renomme un fichier. Syntaxe: rename <avant> <apres>")
                  def rename(avant, apres):
                          renommer, renommer_en = avant, apres
                          rename = connection().rename(renommer, renommer_en) # on renomme
                   
                  @ftpcommand("efface", "Efface un fichier. Syntaxe : efface <fichier>")
                  def efface(fichier):
                          effacer = fichier
                          delete = connection().delete(effacer) # on efface
                   
                  @ftpcommand("creer_rep", "Crée un répertoire (dossier). Syntaxe : creer_rep <nom>")
                  def creer_rep(nom):
                          rep = nom
                          repertoire = connection().mkd(rep) # on crée le répertoire
                   
                  @ftpcommand("sup_rep", "Supprimer un répertoire (dossier). Syntaxe : sup_rep <nom>")
                  def sup_rep(nom):
                          supprimer = nom
                          delete_dir = connection().rmd(supprimer) # on supprime le répertoire
                   
                  @ftpcommand("cmd", "Envoie une commande au serveur. Syntaxe: cmd <commande>")
                  def cmd(commande):
                          resultat = connection().sendcmd(commande) # on envoi la commande
                   
                  # un petit message à propos de la license du script 
                  welcome = '''ftp.py version 1.0, Copyright (C) 2007
                   
                  ftp.py comes with ABSOLUTELY NO WARRANTY. This is free software, and you are
                  welcome to redistribute it under certain conditions; see the GNU General Public
                  License for more details: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html'''
                   
                  def main():
                      global commands
                      print welcome # affichage du message ci-dessus
                      def command_to_argv(cmd):
                          argv = cmd.split(' ') # on met dans une liste les différents arguments
                          argv_size = len(argv) # on compte le nombre de paramètres
                          i = 0 # on initialise le compteur
                          while i < argv_size:
                              if argv[i].endswith('\\') and i + 1 != argv_size: # si c'est un nom de fichier du type : test\ 1.py
                                  argv[i] = argv[i][:-1] + " " + argv[i + 1] # on ajoute le "1.py" à "test", ce qui fait "test 1.py"
                                  del argv[i + 1]
                                  argv_size -= 1
                              i += 1 # on incrémente le compteur
                          return argv # on retourne les arguments
                      while True: # boucle infinie, il va encore falloir utiliser break pour en sortir
                          try: cmd = command_to_argv(raw_input('> ')) # si la commande entrée provoque une erreur...
                          except EOFError: return 0 # on quitte la boucle
                          except KeyboardInterrupt: return 0 # on quitte la boucle
                   
                          cmdname, args = cmd[0], cmd[1:] # cmdname = fonction appelée, args = arguments
                          if not cmdname in commands.keys(): # si la fonction appelée n'existe pas dans le script
                              print "Erreur: '%s' commande incorrecte." % cmdname # on affiche un message d'erreur
                              continue
                          try:
                              commands[cmdname][0](*args)
                          except TypeError:
                              print "Erreur: mauvais nombre d'arguments pour '%s' command." % cmdname
                          except AttributeError:
                              print "Erreur : vous n'êtes pas connecté !"
                      return 0
                   
                  import sys
                  if __name__ == "__main__": sys.exit(main()) # si le script est utilisé comme un module, on n'exécute pas le script
                  


                  Mais pour le serveur qui est haut dessus.
                  • Partager sur Facebook
                  • Partager sur Twitter
                  Anonyme
                    21 décembre 2011 à 11:59:10

                    Connais-tu l'intérêt du décorateur?
                    • Partager sur Facebook
                    • Partager sur Twitter
                      21 décembre 2011 à 12:04:16

                      Non j'ai beaucoup de mal à en comprendre l'utilité mais j’espérer à travers ce script comprendre à quoi il servait et comment sans servir.
                      • Partager sur Facebook
                      • Partager sur Twitter
                      Anonyme
                        21 décembre 2011 à 12:09:31

                        Si tu regardes ton script, tu te rends compte que les décorateurs sont appliqués à plusieurs fonctions.

                        Les décorateurs permettent de faire un prétraitement (identique dans ton script) de chaque fonction, donc dans ton cas ce prétraitement est effectué par la fonction ftpcommand.

                        Quand je parle de prétraitement, je parle de traitement avant l'exécution de la fonction.

                        Edit: ça reste tout de même du sucre syntaxique
                        • Partager sur Facebook
                        • Partager sur Twitter
                          21 décembre 2011 à 13:59:10

                          Tu n'as visiblement pas compris à quoi servait le décorateur dans l'exemple que tu nous as montré :

                          Python 3.2.2 (default, Nov 21 2011, 16:51:01) 
                          [GCC 4.6.2] on linux2
                          Type "help", "copyright", "credits" or "license" for more information.
                          >>> commandes = {}
                          >>> def servcommand(nom, desc):
                          ...     def decor(fn):
                          ...             commandes[nom] = (fn, desc)
                          ...             return fn
                          ...     return decor
                          ... 
                          >>> @servcommand("add", "additionne deux nombres")
                          ... def add(a,b):
                          ...     return a + b
                          ... 
                          >>> @servcommand("mul", "multiplie deux nombres")
                          ... def mul(a, b):
                          ...     return a * b
                          ... 
                          >>> commandes
                          {'mul': (<function mul at 0xb718122c>, 'multiplie deux nombres'), 'add': (<function add at 0xb71811ec>, 'additionne deux nombres')}
                          >>> commandes['add']
                          (<function add at 0xb71811ec>, 'additionne deux nombres')
                          >>> ajouter, commentaire = commandes['add']
                          >>> commentaire
                          'additionne deux nombres'
                          >>> ajouter(2,8)
                          10
                          
                          • Partager sur Facebook
                          • Partager sur Twitter
                          Zeste de Savoir, le site qui en a dans le citron !

                          Commande

                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                          • Editeur
                          • Markdown