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 :

tester si fonction avec return a été exécutée


Sujet :

Python

  1. #1
    Membre du Club
    Inscrit en
    Septembre 2007
    Messages
    103
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 103
    Points : 55
    Points
    55
    Par défaut tester si fonction avec return a été exécutée
    Developpeurs, Bonjour!

    J'aimerais savoir si une fonction a été exécutée ou pas et le cas échéant, récupérer les return en résultant :
    Python 3.2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    def test () :
        a = 10
        b = (20, 30)
        return ( a , b )
     
    class ClassTest :
        # j aimerais entrer dans la boucle if que si test a ete executee    
        if test :
            print ( "ok mais je ne sais pas si test a ete executee?" )
            print ( "comment recuperer les return de test ici -sans utiliser global ?" )
     
        else :
            print ( "no" )
    Merci pour toute info !

  2. #2
    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,

    A mon avis, on devrait pouvoir faire ça avec un décorateur écrit sous forme de classe.

    L'avantage de ce type de décorateur, c'est qu'il peut conserver des infos après chaque appel, par exemple sous forme de dictionnaire. On peut donc tester à n'importe quel endroit du code s'il y a eu un appel (dictionnaire non vide), et si oui, d'obtenir les résultats dans l'ordre où ils ont été obtenus. On peut aussi en même temps conserver les arguments passés à chaque appel.

    Et si ce décorateur était utilisé pour décorer plusieurs fonctions du code, il pourrait conserver dans une variable de classe tous les appels avec pour chaque appel le nom de la fonction appelée, les arguments et le résultat de l'appel, le tout dans l'ordre des appels. Bref, c'est très puissant.

    J'ai fait un tuto sur le sujet: http://python.jpvweb.com/mesrecettes...ateurs_modeles. Attention: c'est du Python 2.7.

    Essaie de faire, et reviens ici si tu n'y arrives pas.

    Tyrtamos
    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

  3. #3
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    +1 pour les décorateurs.

    Une autre idée est que la valeur par défaut d'un argument n'est évalué qu'une fois. A partir de là il est possible d'utiliser une liste en arguments pour stocker les résultats.
    Comprendre que comme cela on a les résultats dans l'ordre ou la fonction a été appelée ainsi que le nombre de fois (len de la liste).

    une combinaison avec un décorateur est intéressante non ?

    @+

    Edit: Pour ce qui est du titre une fonction fait toujours un return.
    Merci d'utiliser le forum pour les questions techniques.

  4. #4
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Bonjour,

    Peut-être que avec des parenthèses à test cela irait un peu mieux:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    class ClassTest :
        # j aimerais entrer dans la boucle if que si test a ete executee    
        if test :
    Ici la condition est vraie parce que test existe dans l'espace de nom global, du moins dans l'exemple et n'est pas nul. Donc les deux print doivent s'exécuter à tous les coups. Mais test n'est pas appelée.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    class ClassTest :
        # j aimerais entrer dans la boucle if que si test a ete executee    
        if test ():
    Comme ceci, test sera appelée, mais dans ton exemple, test renvoie toujours la même chose, on suppose qu'elle pourrait retourner False dans certains cas sinon c'est sans intérêt bien sûr.

  5. #5
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Je repense à python 3 et il m'est venu un doute, comme je l'utilise peu.

    Donc j'ai testé, et je confirme
    vincent@tiemoko:~/Bureau$ python test.py
    ok mais je ne sais pas si test a ete executee?
    comment recuperer les return de test ici -sans utiliser global ?
    vincent@tiemoko:~/Bureau$ python3 test.py
    ok mais je ne sais pas si test a ete executee?
    comment recuperer les return de test ici -sans utiliser global ?

  6. #6
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Je ne vois pas l’intérêt de tester if test() ou alors je n'ai pas compris la question.
    De plus regarder dans les namespaces ne sert à rien (sans utiliser global ?) puisque a = test() / a = le return de test.
    Merci d'utiliser le forum pour les questions techniques.

  7. #7
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Autre chose
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    >>> def test():
    ...     pass
    ...     # return None implicite
    ... 
    >>> if test():
    ...     print('ok')
    ... else:
    ...     print("Ah bon non, c'est None")
    ... 
    Ah bon non, c'est None
    Merci d'utiliser le forum pour les questions techniques.

  8. #8
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 817
    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 817
    Points : 7 110
    Points
    7 110
    Par défaut
    Je ne vois pas l’intérêt de tester if test() ou alors je n'ai pas compris la question.
    ça peut, mais pas dans ce cas en effet, par contre un return peut renvoyer une liste vide ou non, renvoyer True ou False, tuples vides ou non, etc...
    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)

  9. #9
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Aussi. Je voulais juste souligner (par rapport au titre) qu'en Python il n'y as pas de 'procédure'/'fonction'. Une fonction retourne toujours quelque chose, même si c'est None.
    Mon questionnement c'est sur la réponse de VinsS (qui connais ses bases). Ou veux t'il en venir ?
    Merci d'utiliser le forum pour les questions techniques.

  10. #10
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 817
    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 817
    Points : 7 110
    Points
    7 110
    Par défaut
    Pas toujours, on va dire que la normalité veut que se soit le cas, mais on peut tout aussi bien ne rien retourner

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    >>> def test(c):
    ...     global var
    ...     var = c
    ... 
    >>> var = 12
    >>> test(5)
    >>> var
    5
    Pour un dictionnaire, on peut lui attribuer clé et valeur sans retourner de valeur à la fin de la fonction, par exemple.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> def attribuer(a, b):
    ...     dico[a] = b
    ... 
    >>> dico = {}
    >>> for i, j in enumerate(["a", "b", "c", "d"]):
    ...     attribuer(i, j)
    ... 
    >>> dico
    {0: 'a', 1: 'b', 2: 'c', 3: 'd'}
    Mon questionnement c'est sur la réponse de VinsS (qui connais ses bases). Ou veux t'il en venir ?
    J'admets ne pas avoir tout compris non plus
    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)

  11. #11
    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,

    Voilà une solution avec un décorateur (Python 2.7):

    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
    import functools
     
    ###################################################
    class mondecorateur(object):
        """ decorateur qui stocke les résultats d'appels des fonctions décorées """
        adrinst = {} # stocke les noms des fonctions décorées et l'adresse de l'instance de leur décorateur
        def __init__(self, fonc):
            self.fonc = fonc
            self.__class__.adrinst[fonc.func_name] = self # initialise adrinst
            functools.wraps(fonc)(self)
            self.nbappels = 0
            self.resultats = {}
        def __call__(self, *args, **kwargs):
            """ méthode appelée à chaque appel de la fonction décorée """
            # instructions avant l'appel de la fonction décorée
            result = self.fonc(*args, **kwargs)
            # instructions après l'appel de la fonction décorée
            self.nbappels += 1
            self.resultats[self.nbappels] = result
            return result
    Utilisation:

    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
    @mondecorateur
    def test (a,b) :
        return (a, b)
     
    print mondecorateur.adrinst['test'].nbappels
    print mondecorateur.adrinst['test'].resultats
     
    test(1,2)
     
    print mondecorateur.adrinst['test'].nbappels
    print mondecorateur.adrinst['test'].resultats
     
    test(5,7)
     
    print mondecorateur.adrinst['test'].nbappels
    print mondecorateur.adrinst['test'].resultats
     
    test(9,3)
     
    print mondecorateur.adrinst['test'].nbappels
    print mondecorateur.adrinst['test'].resultats
    Ce qui donne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    0
    {}
    1
    {1: (1, 2)}
    2
    {1: (1, 2), 2: (5, 7)}
    3
    {1: (1, 2), 2: (5, 7), 3: (9, 3)}
    On voit qu'au fur et à mesure des appels, le dictionnaire des résultats s'agrandit. On peut donc à n'importe quel moment récupérer le nombre d'appels réalisés, et dans l'ordre tous les résultats successivement obtenus.

    Et si dans le même code on veut suivre une autre fonction, test2() par exemple, le même décorateur fonctionnera de la même façon sans qu'on ait à le réécrire, et le dictionnaire des résultats de ses appels sera obtenu par: mondecorateur.adrinst['test2'].resultats

    Tyrtamos
    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

  12. #12
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    Et en plus simple ?
    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
    50
    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-
    #
    #
    class decorateur(object):
        def __init__(self, fonc=None, d={}):
            self.fonc = fonc
            self.d = d
        def __call__(self, *args, **kwargs):
            result = self.fonc(*args, **kwargs)
            if self.fonc.__name__ in self.d:
                self.d[self.fonc.__name__].append(result)
            else:
                self.d[self.fonc.__name__] = [result]
            return result
        def getitem(self, name):
            if name in self.d:
                return self.d[name]
        def getitemlen(self, name):
            if name in self.d:
                return len(self.d[name])
        def getmembers(self):
            return list(self.d.keys())
     
    @decorateur
    def Foo(a, b):
        return a*b
     
    @decorateur
    def Foo1(a, b):
        return a-b
     
    Foo(1, 5)
    Foo(5, 5)
     
    print("Valeurs de Foo :", decorateur().getitem('Foo'))
    print("Nombre de valeurs pour Foo :", decorateur().getitemlen('Foo'))
     
    Foo1(5, 3)
     
    d = decorateur()
     
    print("Valeurs de Foo1 :", decorateur().getitem('Foo1'))
    print("Nombre de valeurs pour Foo1 :", decorateur().getitemlen('Foo1'))
     
     
    print("Valeurs de Foo2 :", d.getitem('Foo2'))
    print("Nombre de valeurs pour Foo2 :", d.getitemlen('Foo2'))
     
    print("Fonctions utilisées", d.getmembers())
    Output
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Valeurs de Foo : [5, 25]
    Nombre de valeurs pour Foo : 2
    Valeurs de Foo1 : [2]
    Nombre de valeurs pour Foo1 : 1
    Valeurs de Foo2 : None
    Nombre de valeurs pour Foo2 : None
    Fonctions utilisées ['Foo', 'Foo1']
    C'est bien sur moins joli mais sans doute plus compréhensible non ?

    @+

    Edit: Erreur dans le code (None inutile, passé en default value), rectifié.
    Merci d'utiliser le forum pour les questions techniques.

  13. #13
    Membre du Club
    Inscrit en
    Septembre 2007
    Messages
    103
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 103
    Points : 55
    Points
    55
    Par défaut
    Merci pour vos réponses!

    @VinsS: pas possible de faire if test(): car j'exécuterais la fonction dans ce cas. Je veux seulement récupérer les return dans le cas où elle aurait été exécutée. J avais mis if test : de manière générique, en sachant que ça ne teste pas si elle a été exécutée ou pas.

    La classe décorateur va certainement résoudre mon cas (faut que je potasse un peu, je débute). Et tester en Python 3.2, auquel je suis lié parce que c'est pour un script de l'appli graphique Blender. Je donnerai donc un feedback à cet égard.

    La fonction test fait des calculs et renvoie listes et dicos. La classe est une classe de UI dans laquelle j'affiche les résultats des return.

  14. #14
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Citation Envoyé par VinsS Voir le message
    vincent@tiemoko:~/Bureau$ python test.py
    ok mais je ne sais pas si test a ete executee?
    comment recuperer les return de test ici -sans utiliser global ?
    vincent@tiemoko:~/Bureau$ python3 test.py
    ok mais je ne sais pas si test a ete executee?
    comment recuperer les return de test ici -sans utiliser global ?
    J'explique, ceci est le test du code de base TEL QUEL avec python 2 et 3 et démontrait que

    if test:

    sera toujours vrai puisque test est un objet non nul.

    Mon explication était que pour vérifier le retour de 'def test' les parenthèses étaient indispensables et, ceci entendait bien sur que l'exemple donné avait été simplifié mais que 'def test()' aurait pu retourner autre chose que dans l'exemple bien sur

    Citation Envoyé par VinsS Voir le message
    ... mais dans ton exemple, test renvoie toujours la même chose, on suppose qu'elle pourrait retourner False dans certains cas sinon c'est sans intérêt bien sûr.
    Nous sommes bien d'accord que l'exemple donné est un code qui ne sert à rien

    Citation Envoyé par santaflam
    ... Je veux seulement récupérer les return dans le cas où elle aurait été exécutée.
    Santaflam, nous sommes bien d'accord que le return "s'adresse à quelqu'un en réponse à sa question", non ?

    Tu ne peux vérifier le contenu d'un return qu'en exécutant la fonction qui le génère. Les décorateurs dont on te parle, opportunément j'en conviens ne font pas autre chose q'appeler test() eux aussi.

    Autre solution, si ta fonction test était elle aussi dans une classe et ses données résultantes des attributs-arguments de cette classe, tu te simplifierais la vie.

  15. #15
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Citation Envoyé par PauseKawa Voir le message
    Autre chose
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    >>> def test():
    ...     pass
    ...     # return None implicite
    ... 
    >>> if test():
    ...     print('ok')
    ... else:
    ...     print("Ah bon non, c'est None")
    ... 
    Ah bon non, c'est None
    Le cas présent c'est : 'if test:' pas 'if test():'

  16. #16
    Membre du Club
    Inscrit en
    Septembre 2007
    Messages
    103
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 103
    Points : 55
    Points
    55
    Par défaut
    Citation Envoyé par VinsS Voir le message
    Tu ne peux vérifier le contenu d'un return qu'en exécutant la fonction qui le génère
    Il y a peut-être ambiguité dans mon explication: je veux vérifier si la fonction a été exécutée antérieurement. Si oui, j'en prends les return, si non je passe.
    Vérifier le type du contenu de return (True False, liste ou autre) ne m'intéresse pas. En ceci ma fonction test simplifiée ici, colle à mon cas, car si la fonction s'exécute elle retourne de tte façon 2 éléments.
    En aucun cas je ne peux, dans cette boucle if, exécuter la fonction, car celle-ci m'affiche une géométrie, et dans le cas où la fonction a déjà été exécutée j'aurais donc 2 fois la géométrie à l'écran (...).

    Maintenant ma vision n'est peut-être pas réalisable, s'il faut réellement exécuter la fonction pour voir si elle a déjà été exécutée (je peux pas le dire autrement), alors faudra que je change le concept...
    Sans doute comme suit en effet :
    Citation Envoyé par VinsS Voir le message
    Autre solution, si ta fonction test était elle aussi dans une classe et ses données résultantes des attributs-arguments de cette classe, tu te simplifierais la vie.
    Merci pour les idées !

  17. #17
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 817
    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 817
    Points : 7 110
    Points
    7 110
    Par défaut
    Il y a peut-être ambiguité dans mon explication: je veux vérifier si la fonction a été exécutée antérieurement. Si oui, j'en prends les return, si non je passe.
    C'est plus une ambiguïté à ce niveau, pour tester une fonction, faut bien qu'elle retourne quelque-chose.

    à la rigueur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def test(a, b):
        yield (a, b)
     
    liste = [(i, j) for i, j in test(4, 5)]
    if liste:
        # exécuter fonction
    else:
    # si liste vide, traitement

    Maintenant ma vision n'est peut-être pas réalisable, s'il faut réellement exécuter la fonction pour voir si elle a déjà été exécutée (je peux pas le dire autrement), alors faudra que je change le concept...
    Je suppose... Car pour vérifier qu'une fonction s'est exécutée, il faut l'exécuter

    Autre solution, si ta fonction test était elle aussi dans une classe et ses données résultantes des attributs-arguments de cette classe, tu te simplifierais la vie.
    C'est une solution pas obligatoire, mais qui a l'avantage de rendre les choses propres et organisées.
    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)

  18. #18
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    Citation Envoyé par santaflam Voir le message
    Il y a peut-être ambiguité dans mon explication: je veux vérifier si la fonction a été exécutée antérieurement. Si oui, j'en prends les return, si non je passe.
    Citation Envoyé par santaflam Voir le message
    En aucun cas je ne peux, dans cette boucle if, exécuter la fonction, car celle-ci m'affiche une géométrie, et dans le cas où la fonction a déjà été exécutée j'aurais donc 2 fois la géométrie à l'écran (...)
    Est ce a dire que vous voulez que votre fonction soit appelée librement une seule fois (affichage de la géométrie) et que vous souhaitez intercepter les appels (et return) suivant ?
    Comme ceci ?
    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
    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-
    #
    #
    class interceptor(object):
        def __init__(self, fonc=None, d={}):
            self.fonc = fonc
            self.d = d
        def __call__(self, *args, **kwargs):
            if self.fonc.__name__ in self.d:
                result = self.fonc(*args, **kwargs)
                self.d[self.fonc.__name__].append(result)
                return
            else:
                result = self.fonc(*args, **kwargs)
                self.d[self.fonc.__name__] = [result]
                # Ou self.d[self.fonc.__name__] = []
                # si le premier résultat est indifférent.
                return result
        def getvalues(self, name):
            if name in self.d:
                return self.d[name]
     
    @interceptor
    def Foo(a, b):
        return a*b
     
    print(Foo(1, 2))
    print(Foo(2, 2))
    print(Foo(4, 2))
    i = interceptor()
    print(i.getvalues('Foo'))
    @+

    Edit: Vous pouvez aussi faire en sorte que la fonction se bloque elle même.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> def Foo(a, b, l=[]):
    ...     if len(l) == 0:
    ...         l.append('1')
    ...         return a*b
    ... 
    >>> Foo(2, 3)
    6
    >>> Foo(2, 3)
    >>> Foo(2, 3)
    A vous de voir si le return vous intéresse de faire un else et de récupérer les résultats.

    @++
    Merci d'utiliser le forum pour les questions techniques.

  19. #19
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Autre approche
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    >>> def Foo(a, b, l=[]):
    ...     result = a*b
    ...     l.append(result)
    ...     if len(l) == 1:
    ...         return result
    ... 
    >>> Foo(1, 2)
    2
    >>> Foo(1, 2)
    >>> Foo.__defaults__
    ([2, 2],)
    >>> Foo(1, 2)
    >>> Foo.__defaults__
    ([2, 2, 2],)
    @++
    Merci d'utiliser le forum pour les questions techniques.

  20. #20
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    J"allais oublier la condition
    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
    >>> def Foo(a, b, l=[]):
    ...     result = a*b
    ...     l.append(result)
    ...     if len(l) == 1:
    ...         return result
    ...
    >>> Foo.__defaults__[0]
    []
    >>> if len(Foo.__defaults__[0]):
    ...     print('ok')
    ...
    >>> Foo(1, 2)
    2
    >>> if len(Foo.__defaults__[0]):
    ...     print('ok')
    ...
    ok
    Merci d'utiliser le forum pour les questions techniques.

Discussions similaires

  1. Fonction avec getopts ne s'exécute qu'une seule fois
    Par yzoug dans le forum Shell et commandes GNU
    Réponses: 9
    Dernier message: 02/03/2015, 12h44
  2. Fonction avec return table
    Par Aethia dans le forum Sybase
    Réponses: 6
    Dernier message: 11/12/2013, 18h39
  3. Fonction avec un return
    Par baleiney dans le forum Langage
    Réponses: 2
    Dernier message: 03/01/2008, 23h27
  4. Exécution de deux fonction avec ie
    Par musicann dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 15/06/2007, 14h25
  5. Fonction avec divers return possibles
    Par inddzen dans le forum C++
    Réponses: 11
    Dernier message: 28/02/2007, 23h08

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