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 confirmé Avatar de chaying
    Inscrit en
    Mars 2007
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 84
    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 confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 060
    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 : 4 060
    Par défaut
    Il manque le plus important : Le numéro de la ligne où se trouve le message d'erreur.

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

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 068
    Par défaut
    quelle ligne ?

  4. #4
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    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 486
    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...

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

    c'est ligne 18.

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

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

  7. #7
    Membre confirmé Avatar de chaying
    Inscrit en
    Mars 2007
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 84
    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 Expert

    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
    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 confirmé Avatar de chaying
    Inscrit en
    Mars 2007
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 84
    Par défaut
    Merci, j'essaie ca de suite.

  10. #10
    Membre Expert

    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
    Par défaut
    Voir mon edit ci-dessus

  11. #11
    Membre confirmé Avatar de chaying
    Inscrit en
    Mars 2007
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 84
    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 Expert

    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
    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 confirmé Avatar de chaying
    Inscrit en
    Mars 2007
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 84
    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