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 :

Peut-on surcharger None ?


Sujet :

Python

  1. #1
    Membre confirmé Avatar de sopsag
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 224
    Par défaut Peut-on surcharger None ?
    Bonjour,

    pour satisfaire mon désir d'élégance minimaliste j'aimerais pouvoir ne pas tester la "Nonitude" d'un objet avant d'appeler une de ses méthode...

    Je m'explique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    def SpamAndEggs ( obj = None ):
        '''obj peut être None'''
        if obj: # -> il faut le tester avant d'appeler sa méthode
            obj.add_salt( 5 )
     
    class SaltAdder :
        def add_salt ( self,x ):
            print "yummy with some more salt"
     
    yum = SaltAdder()
    SpamAndEggs()
    SpamAndEggs( yum )
    Si obj vaut None, je veux que qu'il ne se passe rien...
    Mais, cela m'oblige à tester obj.
    J'aimerai pouvoir définir un comportement par defaut de None tel que si j'invoque une méthode de None, au lieu de lever une exception, il ne se passe rien. (bien sûr, hors de question de faire des try/except !)

    Un truc dans ce genre :
    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
    class NoneType:
        def add_salt ( self,x ):
            pass # None.add_salt ne fait rien
     
    def SpamAndEggs ( obj = None ):
        '''obj peut être None'''
        obj.add_salt( 5 ) # pas besoin de test !
     
    class SaltAdder :
        def add_salt ( self,x ):
            print "yummy with some more salt"
     
    yum = SaltAdder()
    SpamAndEggs()
    SpamAndEggs( yum )
    On surcharge la classe NoneType pour lui ajouter la méthode add_salt et le tour est joué...
    ben non ! ça ne marche pas.
    Je pense que le problème vient de ce que l'objet None est instancié au début du monde et qu'il ne profite pas des ajouts faits à la classe NoneType.

    Donc, cher Pythoniste, si tu as une idée pour faire marcher mon truc, je suis preneur !

    Hadrien

  2. #2
    Membre émérite
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Par défaut
    Ben en fait c'est vraiment très simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    def SpamAndEggs ( obj = None ):
        '''obj peut être None'''
        if obj is not None: # -> il faut le tester avant d'appeler sa méthode
            obj.add_salt( 5 )
     
    class SaltAdder :
        def add_salt ( self,x ):
            print "yummy with some more salt"
     
    yum = SaltAdder()
    SpamAndEggs()
    SpamAndEggs( yum )
    if suffit de rajouter "is not None"(ou "!=None") au moment de tester obj, ou mieux encore, demander si obj est une instance de SaltAdder, auquel cas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    def SpamAndEggs ( obj = None ):
        '''obj peut être None'''
        if isinstance(obj, SaltAdder): # -> il faut le tester avant d'appeler sa méthode
            obj.add_salt( 5 )
     
    class SaltAdder :
        def add_salt ( self,x ):
            print "yummy with some more salt"
     
    yum = SaltAdder()
    SpamAndEggs()
    SpamAndEggs( yum )
    sera plus approprié

    EDIT: ou bien utiliser un décorator:
    http://www.developpez.net/forums/d685735/autres-langages/python-zope/general-python/decorateurs-quoi-sert/#post4006662
    ou encore remplacer "None" par "SaltAdder()" comme valeur par défaut de obj

  3. #3
    Membre confirmé Avatar de sopsag
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 224
    Par défaut
    euh... j'ai peur de ne pas m'être bien fait comprendre...
    if suffit de rajouter "is not None"(ou "!=None") au moment de tester obj
    ce que je veux c'est ne pas tester justement.

    Si j'appelle obj.add_salt alors que obj vaut None, je veux que l'appel soit "détourné" vers quel que chose d'autre.

    Dans la solution que j'avais imaginée (mais qui ne marche pas), cette autre chose était la méthode add_salt que j'avais ajoutée à NoneType.

    Hadrien

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 99
    Par défaut
    Je ne sais pas trop si on peut faire ce que tu cherches a faire. Mais d'un point de vue strictement personnel, je trouve ca vraiment limite, ce a quoi tu veux arriver.

    Tu autorises explicitement une valeur par défaut à ta méthode, mais tu veux masquer le traitement qui est relatif à ce cas... Qui plus est tu le masque d'une façon très anti-conventionnel...
    Mis à part pour la beauté de savoir si c'est possible, sinon je n'y vois absolument aucun intérêt. Voir pire, je suis intimement persuadé que ce n'est pas une chose a faire. Imagines que tu reviennes voir ton code plusieurs mois après l'écriture, il n'y a presque aucune chance que tu comprennes le comportement sans relire en détail tout le code.

    Si vraiment tu veux éliminer ce test, ne propose pas de valeur par défaut à None. Comme ca, pas de soucis.

    Ne prend pas mal ce que je viens de dire, hein ^^ C'est juste un avis personnel. Ca vient du fait que j'ai fais du support de code pendant des années et je peux te dire que tomber sur un truc pareil ca fait dresser les cheveux sur la tête

  5. #5
    Membre émérite
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Par défaut
    obj est un paramètre pouvant être de n'importe quel type, si on ne le teste pas , comment savoir que obj est bien du type voulu ? Grâce à un decorator on peut éventuellement reporter le test dans ce dernier, mais se passer complètement du test... c'est possible, mais dès lors je rejoins ce que dit Shadowsman : tu pourrais perdre pas mal de temps lors d'une éventuelle future relecture à retracer le cheminement désiré de l'information...

    Si j'appelle obj.add_salt alors que obj vaut None, je veux que l'appel soit "détourné" vers quel que chose d'autre.
    Mais même dans ce cas, ce n'est que déporter le test ailleurs....

  6. #6
    Membre confirmé Avatar de sopsag
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 224
    Par défaut
    Bon ok, vous m'avez convaincu que c'est mal.

    En fait, j'ai trouvé une solution plus propre et plus lisible :

    Déclarer un Default_SaltAdder comme valeur par defaut au paramètre obj Default_SaltAdder a méthode add_salt qui ne fait rien.

    Mais quand même s'il y une solution avec None, je suis curieur de la connaître, juste pour ma culture pythonesque.

    Hadrien

  7. #7
    Membre confirmé Avatar de sopsag
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 224
    Par défaut Mouahaha
    J'ai trouvé THE solution !
    Quand je passe un objet en paramètre, si valeur par defaut est un DoNothingObject, comme son nom l'indique, toute méthode qu'on appelerait ne fera rien.

    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
    class DoNothingObject:
        def _do_nothing (self,*arg): 
            pass
        def __getattr__ (self,name): 
            return self._do_nothing
     
    def Spam ( eggs = DoNothingObject() ):
        eggs.bean( 5 ) # pas besoin de tester !
     
    class DoBean:
        def bean (self,x):
            print "bean( %s )"%str( x )
     
    beans = DoBean()
    Spam( beans ) # appelle bien le 'bean' de 'DoBean'
    Spam() # appelle '_do_nothing'
    Cool non ?

    bon evidemment, mon exemple est débile, mais j'ai rencontré un cas où c'est très utile d'avoir un objet utilisateur qui par defaut ne fait rien...

    Hadrien

  8. #8
    Membre émérite
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Par défaut
    Voici le test que j'ai fait et ce que j'obtient:
    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
    >>> class DoNothingObject:
        def _do_nothing (self,*arg): 
            pass
        def __getattr__ (self,name): 
            return self._do_nothing
     
    >>> DoNothingObject().caca
     
    Traceback (most recent call last):
      File "<pyshell#1>", line 1, in <module>
        DoNothingObject().caca
    TypeError: __repr__ returned non-string (type NoneType)
    >>> a=DoNothingObject()
    >>> a
     
    Traceback (most recent call last):
      File "<pyshell#4>", line 1, in <module>
        a
    TypeError: __repr__ returned non-string (type NoneType)
    par contre ceci marche très bien:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >>> class Foo(object):
        @staticmethod
        def dummy(*args):pass
        def __getattr__(self,name):return self.dummy
     
     
    >>> a=Foo()
    >>> a.caca
    <function dummy at 0x011D6AF0>
    >>> a.caca(50)
    >>>
    En fait ça ne marche qu'a moitié, puisqu'on présuppose que l'attribut réclamé est une fonction. Dans ce cas précis, ça ne fonctionneras pas très bien :
    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
    >>> class Foo(object):
     @staticmethod
     def dummy(*args):pass
     def __getattr__(self,name):return self.dummy
     
    >>> def test1(x=Foo()):
     print x.foo #ne fonctionnera pas comme tout à fait on l'éspère
     
    >>> def test2(x=Foo()):
     print x.foo(123) #par contre ceci marchera très bien
     
    #A l'inverse
     
    ]>>> class Foo(object):
     def __getattr__(self,name):pass
     
    >>> def test1(x=Foo()):
     print x.foo #fonctionnera très bien 
    >>> def test2(x=Foo()):
     print x.foo(123) #par contre ceci ne marchera pas du tout
    Mais cela reste très bancal, puisqu'il faudrait étoffer les possibilité du dummy :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class Foo(object):
     @staticmethod
     def dummy(*args):pass
     def __getattr__(self,name):return self.dummy
     def __setattr__(self,*args):pass
     def __iter__(self): return iter([])
    malgré tout pour que cela reste le plus universel possible, il faut encore bien plus étoffer... Ceci dit, je reste d'avis que ce n'est pas très recommandé : dans bien des cas un code qui s'attend à avoir des objets d'un certain type et se retrouvent avec un autre soulèvent une erreur, par exemple :
    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
    >>> class Foo(object):
     @staticmethod
     def dummy(*args):pass
     def __getattr__(self,name):return self.dummy
     def __setattr__(self,*args):pass
     def __iter__(self): return iter([])
    >>> def test1(x=Foo()):
     x.var1+=1
     
    >>> test1()
    Traceback (most recent call last):
      File "<pyshell#46>", line 1, in <module>
        test1()
      File "<pyshell#45>", line 2, in test1
        x.var1+=1
    TypeError: unsupported operand type(s) for +=: 'function' and 'int'
    >>>

  9. #9
    Membre confirmé Avatar de sopsag
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 224
    Par défaut
    Wow !
    merci pour tout le mal que tu donnes !
    DoNothingObject().caca
    Ca ne marche pas, c'est normal.
    En fait ce ne sont que les appels de méthode que je veux pouvoir récupérer.
    Pour que tu ne me prennes pas pour un fou furieux, voici mon contexte :

    J'ai une classe qui fait plein de trucs qui prennent du temps (upload de gros fichiers sur un site FTP) et je veux pouvoir afficher une indication de progression (de 0% à 100%) pour que l'utilisateur ne s'impatiente pas trop.
    Mais comme je veux que cette classe soit aussi générique que possible, elle ne doit pas savoir comment afficher la progression.
    Elle reçoit donc dans son __init__ un objet "Progress" qui a des méthodes de mises à jour de l'avancement courant.
    Du coup, dans un contexte console, je lui passe un ProgressText qui ne fait que des "print". Dans un contexte avec une GUI en Tk, je lui passe un ProgressTk qui fait des appels directs à Tk.
    Et autant de versions que je veux suivant l'interface graphique que je pourrais choisir à l'avenir.
    Mais, par defaut, mon paramètre Progress vaut DoNothingObject, comme ça, si l'utilisateur ne veut pas de progression du tout, il n'a rien à faire.
    Avant, Progress valait None par defaut, mais ça m'obligeait à tester à chaque appel des méthodes de Progress.
    Voilà toute l'histoire.

    Hadrien

  10. #10
    Membre émérite
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Par défaut
    Haaaa.... Ok ! Oui dans ce contexte c'est un gain de temps (pour le programmeur seulement...), mais il faut faire très attention à tout ce que l'on appelle sur le paramètre progressBar, si ce n'est effectivement que des méthode qui ne sont en fait que des routines (qui ne retournent rien donc), oui, ça fonctionnera , tout de suite ça a une utilité bien plus évidente

  11. #11
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 99
    Par défaut
    Okay je vois mieux, moi aussi.

    Personnelement ce que j'aurais fais c'est un object dans le meme style que ton DoNothingObject() mais je me serais servir de polymorphisme pour arriver a ton resultat.

    Genre ca:
    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
    class EmptyProgress:
        def progress(self): pass
        def autre_fonctions_si_besoin(self): pass
     
    class ShellProgress(EmptyProgress):
        def progress():
            print "fais des trucs"
        def autre_fonctions_si_besoin(self):
            print "fais d'autre trucs"
     
    class QtProgress(EmptyProgress, QtGui.QProgressDialog)
        def __init__(self, owner):
            QtGui.QProgressDialog.__init__(self, owner)
            ....
     
     
    class Principal:
        def __init__(self, progress=EmptyProgress()):
            ....
    Ainsi c'est explicite comment doivent ce comporter tes objets. Mais enfin ca c'est juste un sentiment personnel, je me suis juste dis que c'est comme ca que j'aurais aborder le problème.

  12. #12
    Membre confirmé Avatar de sopsag
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 224
    Par défaut
    Ton approche shadowsam, me plaît bien car elle a un coté très c++ qui est mon langage préféré.

    Mais voilà, en c++, on peut définir une méthode qui prend en param une ref de classe X ce qui nous garantit que le param effectivement passé est (au moins) un fils de X.

    Mais en python, point de typage et point de vérification de l'héritage.
    Donc finalement, si on appelle une méthode qui n'existe pas, on ne s'en apercevra qu'à l'exécution.
    Et du coup, ce n'est pas tellement la peine de définir une relation d'héritage si c'est pour surcharger toutes les méthodes d'une classe.

    Dans ton exemple, à quoi ça sert (sauf peut être à faciliter al compréhension (ce qui est déjà beaucoup me diras-tu)) de faire hériter ShellProgress de EmptyProgress ?
    De toutes façon, ça n'empêchera pas de passer n'importe quoi au __init__ de Principal...

  13. #13
    Membre émérite
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Par défaut
    Il y a quand même moyen de vérifier qu'un objet est une instance d'un classe bien précise, et on peut également vérifier qu'une classe hérite d'une autre classe
    ex:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >>> class Foo(object):
    	pass
     
    >>> class Foo2(Foo):
    	pass
     
    >>> issubclass(Foo2,Foo)
    True
    >>> a=Foo2()
    >>> isinstance(a,Foo)
    True
    Et pour vérifier le type d'objet, il y a type()

  14. #14
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 840
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par sopsag Voir le message
    méthodes de mises à jour de l'avancement courant.
    Du coup, dans un contexte console, je lui passe un ProgressText qui ne fait que des "print". Dans un contexte avec une GUI en Tk, je lui passe un ProgressTk qui fait des appels directs à Tk.
    Et autant de versions que je veux suivant l'interface graphique que je pourrais choisir à l'avenir.
    Mais, par defaut, mon paramètre Progress vaut DoNothingObject, comme ça, si l'utilisateur ne veut pas de progression du tout, il n'a rien à faire.
    Avant, Progress valait None par defaut, mais ça m'obligeait à tester à chaque appel des méthodes de Progress.
    Voilà toute l'histoire.

    Hadrien
    J'ai fait pareil que toi il y a quelque temps... mais moi, au lieu de passer mon objet "Progress" à ma fonction de travail, je lui passais ma méthode "Progress.update".
    Ainsi, ma fonction de travail est plus indépendante et mon code l'est aussi car au lieu de recevoir un objet et d'appeler elle-même la méthode "update" (elle doit donc savoir que l'objet possède une méthode "update" et que se passe-t-il si je change mon IHM et que la méthode devient "affiche" ?), elle reçoit une simple fonction qu'elle appelle
    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
    def travail(fctProgress=None):
        <plein de truc>
        # Ok, on va afficher la progression
        if fctProgress != None: fctProgress(10)
    # travail()
     
    class ProgressText:
        def affiche(self, taux):
             print "%.2f%%" % taux 
     
    class myProgress(QProgressBar):
        def totitop(self, taux)
             self.setProgress(taux)
     
    # Ok, j'appelle travail avec un progressText
    travail(ProgressText)
     
    # Ok, j'appelle travail avec une progressBar
    travail(myProgress().totitop)
    Arf, évidemment je suis obligé de vérifier que ma fonction n'est pas None. Mais cela ne me gène pas...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  15. #15
    Membre confirmé Avatar de sopsag
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 224
    Par défaut
    Bon allez, comme vous être super sympa, je vous envoie le code de ma classe :
    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
    class ProgressBar:
        """Gère une barre de progression"""
     
        def __init__ (self,printer,msg=''):
            """printer : prend en paramètre un message et un flottant entre 0 et 1"""
            self.reset( printer,msg )
     
        def __default_printer (self , str , progress ):
            print '%s %.3g%%' %( str,progress*100 )
     
        def reset(self,printer=None,msg=None):
            self.ratio                = [1.0]
            self.loop_count           = 100
            self.loop_index           = 0
            self.loop_inc             = 1.0/self.loop_count
            self.progress             = 0.0
            self.printer              = self.__default_printer
            if msg:     self.msg      = msg
            if printer: self.printer  = printer
            return self
     
        def set_message (self,msg):
            self.msg = msg
     
        def enter (self,ratio):
            self.ratio.append( ratio )
            return self
     
        def exit (self):
            self.ratio.pop()
            return self
     
        def loops (self,nb):
            self.loop_count = nb
            self.loop_index = 0
            if nb > 0 : self.loop_inc = 1.0/self.loop_count
            else      : self.loop_inc = 1
            return self
     
        def loop (self):
            self.loop_index += 1
            prod = reduce( lambda a,b : a*b , self.ratio )
            self.progress += prod*self.loop_inc
            self.printer( self.msg,self.progress )
            return self
    L'idée de ce bazar est de faciliter l'affichage de l'avancement dans des sous routines qui ne savent pas où on en est au niveau global.
    Quand on rentre dans une sous routine, on appelle enter avec un intervalle relatif et la sous routine croit qu'elle avance de 0% à 100% alors qu'elle reste dans l'intervalle fixé par l'appelant.
    Quand on sort, on appelle exit et le tour est joué.
    Je ne suis pas sûr d'être très clair, mais le code le sera à ma place...
    (c'est vrai que ça manque cruellement de commentaires...)
    En tous cas, passer seulement une méthode ne suffit pas.

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

Discussions similaires

  1. Peut-on surcharger un serveur avec Curl ?
    Par Maki69 dans le forum Langage
    Réponses: 3
    Dernier message: 28/11/2013, 00h55
  2. Réponses: 4
    Dernier message: 30/09/2012, 08h50
  3. Réponses: 8
    Dernier message: 20/11/2002, 11h50
  4. Créer une fenêtre flottante qui ne peut avoir le focus
    Par BestofMac dans le forum Composants VCL
    Réponses: 4
    Dernier message: 17/07/2002, 10h46
  5. Un Sender peut-il s'auto-détruire lors d'un onClick?
    Par Flo. dans le forum C++Builder
    Réponses: 2
    Dernier message: 17/07/2002, 10h31

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