IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Aide sur script


Sujet :

Python

  1. #1
    Membre du Club Avatar de chaying
    Inscrit en
    Mars 2007
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 84
    Points : 57
    Points
    57
    Par défaut Aide sur script
    Bonjour

    Je voudrais construire une classe qui herite de Dialog afin d'ajouter une fonction d'exit propre a toutes ses fonctions en general. J'ai ecrit le code suivant qui est suppose recevoir le nom de la fonction en argument :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    #! /usr/bin/env python
    import dialog
     
     
    class DialogManager(dialog.Dialog):
     
        def __init__(self, applicationtitle="No title", function=dialog.Dialog.menu):
     
            dialog.Dialog.__init__(self)
            self.applicationtitle = applicationtitle
     
            self.add_persistent_args(["--backtitle", self.applicationtitle])
            self.TIMER = 0
     
        def dialogBox(self, function="menu", data=[("0", "title"), ("1", "menu1")], height=35, width=54, menu_height=7, **kwargs):
     
            while 1:
                (code, tag) = function(data[0][1], height=height, width=width, menu_height=menu_height, choices=data[1:])
                if DialogManager.handle_exit_code(self, code):
                    break
            return code, tag
     
        def handle_exit_code(self, code):
     
            if code in (self.DIALOG_CANCEL, self.DIALOG_ESC):
                if code == self.DIALOG_CANCEL:
                    msg = "You chose cancel in the last dialog box. Do you want to exit ?"
                else:
                    msg = "You pressed ESC in the last dialog box. Do you want to exit ?"
     
                if self.yesno(msg) == self.DIALOG_OK:
                    sys.exit(0)
                return 0
            else:
                return 1
     
    def main():
        try:
            d = DialogManager("df")
            d.dialogBox()
            #print d.code, d.tag, d.width
     
        except dialog.error, exc_instance:
            sys.stderr.write("Error:\n\n%s\n" % exc_instance.complete_message())
            sys.exit(1)
     
        sys.exit(0)
     
    if __name__ == "__main__": main()
    Mais j'obtiens le message d'erreur suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TypeError: 'str' object is not callable
    J'ai essaye plusieurs syntaxes mais je n'arrive pas a comprendre celle qui pourrait marcher ici..

    Merci

  2. #2
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 813
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 813
    Points : 7 102
    Points
    7 102
    Par défaut
    Il manque le plus important : Le numéro de la ligne où se trouve le message d'erreur.
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  3. #3
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 046
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 046
    Points : 1 376
    Points
    1 376
    Par défaut
    quelle ligne ?

  4. #4
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Cette erreur se produit quand on essaye d'exécuter une simple variable chaine:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    x = "toto"
    print x()
     
    Traceback				
        <module>	D:\.......\test.py  	25		
    TypeError: 'str' object is not callable
    Il ne reste plus qu'à connaitre la ligne...
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  5. #5
    Membre du Club Avatar de chaying
    Inscrit en
    Mars 2007
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 84
    Points : 57
    Points
    57
    Par défaut
    Oops desole

    c'est ligne 18.

  6. #6
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 046
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 046
    Points : 1 376
    Points
    1 376
    Par défaut
    function="menu" ???

  7. #7
    Membre du Club Avatar de chaying
    Inscrit en
    Mars 2007
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 84
    Points : 57
    Points
    57
    Par défaut
    Je voulais en fait utiliser la meme technique que lors d'un switch.

    Python permet d'utiliser des strings comme nom de fonction, qui sont consideres comme fonction quand on les ecrit nom() si je ne me trompe ?

  8. #8
    Membre éprouvé

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Points : 1 273
    Points
    1 273
    Par défaut
    Citation Envoyé par chaying Voir le message
    Je voulais en fait utiliser la meme technique que lors d'un switch.

    Python permet d'utiliser des strings comme nom de fonction, qui sont consideres comme fonction quand on les ecrit nom() si je ne me trompe ?
    Vous vous trompez*!

    Si vous assignez un str à function, function est un str, et donc non-callable.

    Certaines bibliothèques/api (Django, BPY de Blender, etc.) permettent effectivement de passer un str à la place d’un callable, la dite bibliothèque se chargeant alors de chercher (dans un dict, un module, etc.) l’objet callable correspondant à ce nom – mais ce n’est pas une fonctionnalité de python lui-même*!

    PS : Dans le cas d’une fonction (ou d’une variable, d’ailleurs) disponible dans l’espace de nom global, le plus simple pour réaliser ça est d’utiliser le builtin globals():

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def menu():
        print("Hello World!")
     
    def run(function="menu"):
        function = globals().get(function, function)
        if callable(function):
            function()

  9. #9
    Membre du Club Avatar de chaying
    Inscrit en
    Mars 2007
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 84
    Points : 57
    Points
    57
    Par défaut
    Merci, j'essaie ca de suite.

  10. #10
    Membre éprouvé

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Points : 1 273
    Points
    1 273
    Par défaut
    Voir mon edit ci-dessus

  11. #11
    Membre du Club Avatar de chaying
    Inscrit en
    Mars 2007
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 84
    Points : 57
    Points
    57
    Par défaut
    Desole pour la bouletitude..

    J'ai commence par lire : http://python.developpez.com/cours/D...nd_globals.php
    et ecrire un script simple pour voir si je comprenais.. J'en vois qui ris, c'est pas gentil.

    1re methode :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    import dialog
     
    def run(function="infobox"):
        function = globals().get(function, function)
        if callable(function):
            function()
        print function, globals().items(), locals().items()
     
    run()
    Message d'erreur si j'enleve le if :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    function()
    TypeError: 'str' object is not callable
    Resultat : Ca ne change rien, "function" n'est toujours callable et reste considere comme un string. Et aucune des fonctions de Dialog n'apparait
    dans les espaces de noms.

    Je ne comprends pas pourquoi les fonctions de Dialog reste inaccessible ?

    En faisant d'autres recherches, je suis tombe sur "getattr" et ai reecris un script :

    2eme methode :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    import dialog
     
    function = getattr(dialog.Dialog, 'infobox')
    result = function(d, text="vide")
    La ca marche.. avec "infobox" parce qu'avec "menu", j'obtiens le message d'erreur suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    dialog.py, line 764, in _wait_for_program_termination
        "environment variable)" % exit_code)
    dialog.DialogError: <DialogError: the dialog-like program exited with code 3 (was passed to it as the DIALOG_ERROR
     environment variable)>
    De plus, quand j'essaie de mettre la version du script qui marche en classe, c'est a dire remplacer "def dialogBox(self, function="infobox")" par la fonction suivante dans le script du premier post :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    def run(self, function="infobox"):
        function = getattr(dialog.Dialog, function)
        text = "vide"
     
        code, tag = function(text)
    J'obtiens le message d'erreur suivant, logique :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TypeError: unbound method infobox() must be called with Dialog instance as first argument (got str instance instead)
    J'ai essaye d'instancier Dialog a l'interieur de la fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    def run(self, function="infobox"):
            function = getattr(dialog.Dialog, function)
            text = "vide"
            d = dialog.Dialog()
            code, tag = function(d, text)
    Mais :
    1 - ca me parait bizzare d'avoir a instancier 3 fois la classe - une fois dans "init", "main" et une autre dans la fonction
    2 - la boite s'affiche bien mais j'obtiens encore un message d'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    code, tag = function(d, text)
    TypeError: 'int' object is not iterable
    Je ne vois meme pas de quel "int" il me parle

    Voila, quelques explications ou liens vers une doc pouvant m'eclairer seraient bienvenue.

    Je veux bien payer un cafe a ceux qui se sont endormis lors de la lecture de ce long post.

    Merci

  12. #12
    Membre éprouvé

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Points : 1 273
    Points
    1 273
    Par défaut
    Aïe, oui, c’est un peu la salade, là…

    Bon, dans ton cas, globals() n’est effectivement pas adapté, mais tu ne dois pas non plus utiliser directement dialog.Dialog. Ta classe dérivant de Dialog, elle en contient normalement tout le contenu, dont les fameux menu(), infobox(), etc., donc c’est sur self que tu dois utiliser getattr() –*quelque chose comme ça*:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    def run(self, function="infobox"):
            function = getattr(self, function)
            text = "vide"
            code, tag = function(self, text)
    Ou, en repartant du code de départ*:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    #! /usr/bin/env python
    import dialog
     
     
    class DialogManager(dialog.Dialog):
     
        def __init__(self, applicationtitle="No title", function=dialog.Dialog.menu):
     
            dialog.Dialog.__init__(self)
            self.applicationtitle = applicationtitle
     
            self.add_persistent_args(["--backtitle", self.applicationtitle])
            self.TIMER = 0
     
        def dialogBox(self, function="menu", data=[("0", "title"), ("1", "menu1")], height=35, width=54, menu_height=7, **kwargs):
            function = getattr(self, function)
            while 1:
                (code, tag) = function(self, data[0][1], height=height, width=width, menu_height=menu_height, choices=data[1:])
                if DialogManager.handle_exit_code(self, code):
                    break
            return code, tag
     
        def handle_exit_code(self, code):
     
            if code in (self.DIALOG_CANCEL, self.DIALOG_ESC):
                if code == self.DIALOG_CANCEL:
                    msg = "You chose cancel in the last dialog box. Do you want to exit ?"
                else:
                    msg = "You pressed ESC in the last dialog box. Do you want to exit ?"
     
                if self.yesno(msg) == self.DIALOG_OK:
                    sys.exit(0)
                return 0
            else:
                return 1
     
    def main():
        try:
            d = DialogManager("df")
            d.dialogBox()
            #print d.code, d.tag, d.width
     
        except dialog.error, exc_instance:
            sys.stderr.write("Error:\n\n%s\n" % exc_instance.complete_message())
            sys.exit(1)
     
        sys.exit(0)
     
    if __name__ == "__main__": main()
    (Code non testé.)

  13. #13
    Membre du Club Avatar de chaying
    Inscrit en
    Mars 2007
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 84
    Points : 57
    Points
    57
    Par défaut
    Tout d'abord : desole, ca m'a pris un peu de temps et quelques cours pour comprendre mais voila le code qui fonctionne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if callable(getattr(dialog.Dialog, function)):
                fn = getattr(dialog.Dialog, function)
                fn(self, data[0], height, width)
    En effet, le precedent ne foncionnait pas.

    Merci neanmoins a mont29 pour son aide

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. demande d'aide sur scripts
    Par threepwood dans le forum Linux
    Réponses: 5
    Dernier message: 06/08/2008, 13h34
  2. votre aide sur script fusionne cvs fichiers
    Par chapeau_melon dans le forum VBScript
    Réponses: 0
    Dernier message: 27/06/2008, 16h07
  3. [Upload] aide sur script upload
    Par Jopa5 dans le forum Langage
    Réponses: 4
    Dernier message: 25/11/2007, 15h30
  4. [Oracle 9.2] Aide sur script SQL
    Par fmoriet dans le forum Langage SQL
    Réponses: 3
    Dernier message: 01/02/2006, 08h25
  5. [intermedia] besoin d'aide sur script PL/SQL
    Par SteelBox dans le forum PL/SQL
    Réponses: 8
    Dernier message: 05/01/2004, 19h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo