1) Le code répétitif En vrai, moi j'aurais codé ça autrement, en utilisant un décorateur pour chaque fonction exportée dans la ligne de commande, genre : @ftpcommand("nomcourt", "description") def fonction(): ... Avec ftpcommand un décorateur qui append la fonction dans une liste, avec le nom court et la description associée. Ensuite, dans le main, on va chercher les fonctions dans la liste, et ça rend le code beaucoup plus beau et moins répétitif. 2) Pas de vérification du nom du module En effet, rien ne m'empécherais normalement d'utiliser son module en l'important (import nom_du_module). Or là, je ne peux pas, car il ne vérifie pas comment son module a été appellé (lancement direct, dans ce cas __name__ == "__main__", ou importation, __name__ == "nom_du_module"), ce qui lance la boucle infinie même en cas d'importation. Code corrigé : (j'ai pas testé, écrit en live dans kedit) --------------------------------------------------------- #!/usr/bin/env python #-*- encoding: utf-8 -*- # # ftp.py # FTP CLI interface # # Copyright (C) 2007 delroth # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import ftplib as ftp commands = {} def connection(value=None): if value == None: return getattr(connection, 'value', None) else: connection.value = value return value def ftpcommand(nom_court, description): def decorator(function): global commands commands[nom_court] = (function, description) return function return decorator @ftpcommand("help", "Affiche l'aide des commandes") def help(): global commands keys = commands.keys() keys.sort() print '\n'.join(["%s: %s" % (i, commands[i][1]) for i in keys]) @ftpcommand("connect", "Se connecte au serveur. Syntaxe: connect ") 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() # Coder ici les autres fonctions # J'en profite pour implémenter la syntaxe "commande arg1 arg2 arg3 ...", tant # que j'y suis :-' . welcome = '''ftp.py version 1.0, Copyright (C) 2007 delroth 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 def command_to_argv(cmd): argv = cmd.split(' ') argv_size = len(argv) i = 0 while True: if i >= argv_size: break if argv[i].endswith('\\'): argv[i] = argv[i][:-1] + argv[i + 1] del argv[i + 1] argv_size -= 1 i += 1 return argv while True: try: cmd = command_to_argv(raw_input('> ')) except EOFError: return 0 except KeyboardInterrupt: return 0 cmdname, args = cmd[0], cmd[1:] if not cmdname in commands.keys(): print "Error: '%s' command not found." % cmdname continue try: commands[cmdname][0](*args) except TypeError: print "Error: wrong number of arguments for '%s' command." % cmdname except AttributeError: print "Error: you are not yet connected !" return 0 import sys if __name__ == "__main__": sys.exit(main())