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 :

Supprimer l'instance créée à l'init c'est possible ?


Sujet :

Python

  1. #1
    Membre averti
    Inscrit en
    Mars 2006
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 15
    Par défaut Supprimer l'instance créée à l'init c'est possible ?
    Bonjour,

    Sur une classe je fais un contrôle d'arguments, et je voudrais que l'instance ne soit pas créée si les tests sur les arguments ne sont pas réussis.

    Je voudrais en plus ne pas passer par des décorateurs (python 2.3).

    J'imaginais un truc du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class A():
        def __init__(self, arg1, arg2):
            try:
                assert test1()
                assert test2()
                etc...
            except AssertionError:
                print "les arguments ne sont pas corrects"
                del self
    Mais tout ce que fait le "del self" est d'enlever self de l'espace de noms à l'intérieur de la classe apparemment.

    Moi ce que je voudrais c'est si un argument ne passe pas les test, obtenir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    >>> a = A(arg1, arg2)
    les arguments ne sont pas corrects
    >>> a
    NameError exception bla bla bla...
    Est-ce possible ? Vous avec des idées ??

    Merci d'avance.

  2. #2
    Membre émérite

    Profil pro
    Inscrit en
    Août 2004
    Messages
    723
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 723
    Par défaut
    Tu peux relancer une erreur, ça devrait être suffisant.

  3. #3
    Membre averti
    Inscrit en
    Mars 2006
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 15
    Par défaut
    Je comprends pas trop la réponse...

    Une petite explication ??

  4. #4
    Membre émérite

    Profil pro
    Inscrit en
    Août 2004
    Messages
    723
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 723
    Par défaut
    Ce que je propose, c'est qu'au lieu de te contenter d'un print, tu relances une erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #[...]
    except AssertionError:
        raise ValueError("Les arguments ne sont pas corrects")

  5. #5
    Membre averti
    Inscrit en
    Mars 2006
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 15
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Tu peux m'expliquer ce que tu voulais faire?
    Ben avoir une classe qui a ce comportement là si les arguments passent pas les tests (et qu'importe le type de test - sur le type, les valeurs etc...):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> a = A(arg1, arg2)
    les arguments ne sont pas corrects
    >>> a
    Traceback (most recent call last):                                    
      File "<stdin>", line 1, in <module>                                 
    NameError: name 'a' is not defined
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #[...]
    except AssertionError:
        raise ValueError("Les arguments ne sont pas corrects")
    Bah oui mais non... si je déclenche une exception et que je ne la gère pas derrière, mon code s'arrête et basta.

    Moi ce que je veux c'est que mon code ne s'arrête pas..

  6. #6
    Membre averti
    Inscrit en
    Mars 2006
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 15
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Tu dois bien savoir quel type d'argument tu attends, non?
    Oui je les connais, et je sais utiliser les if, else, isinstance etc merci bien.
    Mais là n'est pas la question, on s'en fout du type de test !

    Donc disons que je pose une question d'ordre GENERALE :

    Donc mon but est de d'avoir une classe, appelons-là 'A' qui nécessite N arguments (et M tests permettant de les valider).
    Si je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    a = A(arg1, arg2, ..., argN)
    Si un des arguments ne passent pas les tests, je voudrais, et cela sans déclencher d'exception (je ne veux pas arrêter mon code) que l'instance 'a' n'existe pas (ie. de telle sorte qu'appeler 'a' soulève une exception).

    Le but du jeu étant de n'avoir que des instances de cette classe valides, sans avoir besoin de passer par un attribut supplémentaire genre a.valide = True.

    J'espère avoir été assez clair,

    Merci.

  7. #7
    Membre averti
    Inscrit en
    Mars 2006
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 15
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Utilises isinstance alors
     
     isinstance(var, maclasse)
     
     Qui va te donner le résultat True ou False
     
     Et là tu crées une exception
    Alors soit je suis à côté de la plaque, soit c'est un bot qui me répond.

    Quelqu'un de soit sensé, soit pédagogue (suivant le côté de la plaque où je me trouve) pourrait-il me répondre ?

  8. #8
    Expert confirmé
    Avatar de Guigui_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2002
    Messages : 1 864
    Par défaut
    Pourquoi tu ne fais pas ce qu'on te propose avec le raise dans la définition de la classe

    puis
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    try: a = A(arg1, arg2, ...)
    except: pass

  9. #9
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    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 062
    Par défaut
    Pourquoi tu ne fais pas ce qu'on te propose avec le raise dans la définition de la classe
    Je me demande si il ne confond pas alias et instanciation

    Je suppose mais c'est tellement mal exprimé qu'il veut créer un constructeur et un destructeur __del__

    du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    def __del__(self): #"destructeur"
        a.__del__(self) # appel du destructeur parent
    puis utiliser pour supprimer une référence

    del reference


  10. #10
    Membre averti
    Inscrit en
    Mars 2006
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 15
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    try: a = A(arg1, arg2, ...)
    except: pass
    Merci pour cette proposition de solution. C'est vrai que ça marche, mais ça ne résoud pas mon besoin: il me faut une classe avec tout le nécessaire à l'intérieur (c'est un besoin particulier j'en conviens mais c'est comme ça).

    Je suppose mais c'est tellement mal exprimé
    Bon ben bizarrement je trouve que le bout de code qui suit explicite assez clairement ce que je souhaiterais obtenir non ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> a = A(arg1, arg2)
    les arguments ne sont pas corrects
    >>> a
    Traceback (most recent call last):                                    
      File "<stdin>", line 1, in <module>                                 
    NameError: name 'a' is not defined
    Donc possible ou bien ?

  11. #11
    Membre confirmé Avatar de KINENVEU
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 184
    Par défaut
    je trouve ton probleme assez clair et interessant,
    malheureusement, je n'ai pas trouve de solution.

    je serais tres curieux d'en connaitre une.

  12. #12
    Membre confirmé Avatar de KINENVEU
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 184
    Par défaut
    j'aimerai relancer le sujet car je n'ai toujours pas trouve de solution.

  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
    J'ai réussi d'une fçon pas très 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
    >>> class Foo(object):
        def __init__(self,i):
            if type(i)!=int: raise
    >>> def define(name,instcode):
        try:
            exec('globals()["%s"]=%s'%(name,instcode))
        except:
            print 'pas bon'
    >>> define('a','Foo(1.2)')
    pas bon
    >>> a
     
    Traceback (most recent call last):
    File "<pyshell#246>", line 1, in <module>
    a
    NameError: name 'a' is not defined
    >>> define('a','Foo(1)')
    >>> a
    <__main__.Foo object at 0x011DA430>
    C'est pas exactement, ce que l'auteur recherchait mais en même temps, on peux pas del une variable en cours de definition (c'est en tous cas ma conclusion)... donc je pense que la meilleur façon d'approcher le resultat escompté est d'apliquer le principe du try dans une fonction, histoire de pouvoir dynamiser un peu la chose... non ?

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

    D'après ce que je crois comprendre, quand on lance une affectation du genre "a = A(arg1, arg2, ...)", il y a d'abord exécution de la partie droite, puis ensuite affectation du résultat à la variable.

    Cela veut dire une chose: pendant l'initialisation de la classe avec __init__, on ne peut pas supprimer la liaison avec la variable parce que cette liaison n'existe pas encore. Et si on trouve un moyen pour faire échouer l'initialisation de la classe, la tentative d'affectation avec un objet qui n'existe pas va échouer: et arrêtera le programme s'il n'y a pas le try:...except:.

    En résumé, je ne crois pas qu'il y a une autre solution que celle déjà donnée (et qui marche!): déclencher une exception par raise pendant l'initialisation de la classe, et la gérer avec un try: ... except:

    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 Test(object):
        def __init__(self, x=None):
            self.toto = "l'instance existe"
            if x==1:
                raise ValueError
     
    try:
        a=Test(5)
    except:
        print "Erreur: variable non conforme!"
     
    print a.toto
     
    try:
        b=Test(1)
    except:
        print "Erreur: variable non conforme!"
     
    print b.toto
    Ce code donne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    l'instance existe
    Erreur: variable non conforme!
     
    Traceback (most recent call last):
      File "C:\Python25\Pydev\test\test_AN.py", line 24, in <module>
        print b.toto
    NameError: name 'b' is not defined
    Tyrtamos

  15. #15
    Membre Expert
    Avatar de DelphiManiac
    Homme Profil pro
    Homme à tout faire
    Inscrit en
    Mars 2002
    Messages
    1 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Homme à tout faire
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 147
    Par défaut
    Il me parait plus simple de ne pas créer l'instance, plutôt que de la supprimer.

    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
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
     
    class Test(object):
        def __new__(cls, arg1):
            try:
                v = int(arg1)
                return object.__new__(cls)
            except:
                print "les arguments ne sont pas corrects"
                return None
     
        def __init__(self, arg1):
            self.arg1 = arg1
            pass
     
        def show(self):
            print "arg1=", self.arg1
     
    for v in ('12', 'aa', '23'):    
        t = Test(v)
        if t:
            t.show()

Discussions similaires

  1. Supprimer une table créée
    Par stfanny31 dans le forum Débuter
    Réponses: 8
    Dernier message: 13/06/2008, 13h27
  2. supprimer des labels crées dynamiquement
    Par patbou dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 19/10/2007, 13h53
  3. 2 instances de reporting services 2000, c'est possible ?
    Par Ruddy dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 03/08/2006, 15h37
  4. C'est possible de supprimer une balise ??
    Par solp dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 12/04/2006, 19h23

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