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 :

Petite question sur l'ordre des déclarations en python.


Sujet :

Python

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2014
    Messages : 51
    Points : 44
    Points
    44
    Par défaut Petite question sur l'ordre des déclarations en python.
    Bonjour,

    Comme indiqué dans le titre je me pose une petite question basique sur l'ordre de déclaration en python (aussi bien pour les classes que pour les fonctions je suppose).

    J'ai crée un petit fichier pour expérimenter et je l'ai exécuté.
    J'ai obtenu une NameError.

    Voici le fichier en question :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #!/usr/bin/python
     
    class testbis:
        obj = test()
     
        def __init__(self):
            self.name = "testbis example"
     
    class test:
        obj = testbis()
     
        def __init__(self):
            self.name = "testbis example"
    J'ai très bien compris l'erreur : J'utilise la classe test avant de l'avoir définie.
    Dans ce cas il suffit de remettre la classe test au dessus de la classe testbis.
    Seulement je suppose qu'on peut se retrouver parfois avec des cas tordus où deux classes sont chacune une dépendance de l'autre.
    Et dans ce cas, changer l'ordre des classes dans mon fichier ne résout rien!
    Je vais faire un parallèle avec le C.

    En C, quand une fonction A nécessite une fonction B mais que la fonction B n'est définie que plus bas, se contenter de rajouter la déclaration la fonction B au dessus de la fonction A (juste avec son prototype) peut résoudre le problème.
    D'où ma question :
    Existe-t-il une manière de faire analogue en Python?

    Merci d'avance!

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Si on peut pas "déclarer" avant, on peut initialiser après:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class testbis:
        pass
     
    class test:
        obj = testbis()
     
    testbis.obj = test()
    par contre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def f():
        g()
     
    def g():
        f()
    hormi le fait que çà boucle, "interprété" = "l'objet doit être défini quand on en a besoin".

    On peut donc "combiner" les deux, par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    def create_test(klass):
        class test:
            obj = klass()
        return test
     
    def create_testbis(klass):
        class testbis:
            obj = klass()
        return bistortes
     
    test = create_test(testbis)
    testbis = create_test(test)
    mais il faut mettre encore plus de jus pour que ça fonctionne.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    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
    J'ai très bien compris l'erreur : J'utilise la classe test avant de l'avoir définie.
    Salut,

    Non, tu peux utiliser une classe définie plus loin dans le script, sans problème.
    Pas de cette manière cependant, parce que Python créera les attributs de classe dans l'ordre de lecture, il faudra donc, dans ce cas précis, en faire des attributs d'instance.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    class testbis: 
        def __init__(self):
            self.obj = test()
    Seulement je suppose qu'on peut se retrouver parfois avec des cas tordus où deux classes sont chacune une dépendance de l'autre.
    Si tu veux dire ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class testbis: 
        def __init__(self):
            print("testbis example")
            self.obj = test()
     
    class test:
        def __init__(self):
            print("testbis example")
            self.obj = testbis()
     
    t = test()
    ça ne peux pas se faire, pour une raison aisément compréhensible:
    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
     
    vincent@tiemoko:~/Bureau$ python3 cls.py
    testbis example
    testbis example
    .....[skip]
    testbis example
    testbis example
    Traceback (most recent call last):
      File "cls.py", line 13, in <module>
        t = test()
      .......[skip]
      File "cls.py", line 11, in __init__
        self.obj = testbis()
      File "cls.py", line 6, in __init__
        self.obj = test()
    RuntimeError: maximum recursion depth exceeded

  4. #4
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    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 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    C'est un cas de figure plutôt rare, et comme j'ai beaucoup travaillé en pascal avec un compilateur en une seule passe, j'évite ça.

    Quand ça m'arrive, je fais comme le dit wiztricks:

    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
    class testbis:
     
        obj = None
     
        def __init__(self):
     
            self.name = "testbis example"
     
     
    class test:
     
        obj = testbis()
     
        def __init__(self):
     
            self.name = "test example"
     
    testbis.obj = test()
     
    #############################################################################
    if __name__ == '__main__':
     
        x = testbis()
     
        print(x.name)
     
        print(x.obj.name)
    Ce qui donne bien:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    testbis example
    test example
    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
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2014
    Messages : 51
    Points : 44
    Points
    44
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Salut,

    Si on peut pas "déclarer" avant, on peut initialiser après:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class testbis:
        pass
     
    class test:
        obj = testbis()
     
    testbis.obj = test()
    par contre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def f():
        g()
     
    def g():
        f()
    hormi le fait que çà boucle, "interprété" = "l'objet doit être défini quand on en a besoin".

    On peut donc "combiner" les deux, par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    def create_test(klass):
        class test:
            obj = klass()
        return test
     
    def create_testbis(klass):
        class testbis:
            obj = klass()
        return testbis
     
    test = create_test(testbis)
    testbis = create_test(test)
    - W
    C'est exactement ce que je cherchais à savoir, merci.

    Citation Envoyé par VinsS Voir le message
    Salut,

    Non, tu peux utiliser une classe définie plus loin dans le script, sans problème.
    Pas de cette manière cependant, parce que Python créera les attributs de classe dans l'ordre de lecture, il faudra donc, dans ce cas précis, en faire des attributs d'instance.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    class testbis: 
        def __init__(self):
            self.obj = test()


    Si tu veux dire ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class testbis: 
        def __init__(self):
            print("testbis example")
            self.obj = test()
     
    class test:
        def __init__(self):
            print("testbis example")
            self.obj = testbis()
     
    t = test()
    ça ne peux pas se faire, pour une raison aisément compréhensible:
    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
     
    vincent@tiemoko:~/Bureau$ python3 cls.py
    testbis example
    testbis example
    .....[skip]
    testbis example
    testbis example
    Traceback (most recent call last):
      File "cls.py", line 13, in <module>
        t = test()
      .......[skip]
      File "cls.py", line 11, in __init__
        self.obj = testbis()
      File "cls.py", line 6, in __init__
        self.obj = test()
    RuntimeError: maximum recursion depth exceeded
    Mais si justement je cherche à en faire un attribut pour ma classe? c'est sans doute un problème que je peux rencontrer pour autre-chose que les classes de toute façon.
    J'ai bien songé à ce soucis de récursion, mais je me suis dit qu'on pouvait sans doute trouver un moyen de l'éviter en mettant un compteur ou une condition de fin.

    Citation Envoyé par tyrtamos Voir le message
    Bonjour,

    C'est un cas de figure plutôt rare, et comme j'ai beaucoup travaillé en pascal avec un compilateur en une seule passe, j'évite ça.

    Quand ça m'arrive, je fais comme le dit wiztricks:

    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
    class testbis:
     
        obj = None
     
        def __init__(self):
     
            self.name = "testbis example"
     
     
    class test:
     
        obj = testbis()
     
        def __init__(self):
     
            self.name = "test example"
     
    testbis.obj = test()
     
    #############################################################################
    if __name__ == '__main__':
     
        x = testbis()
     
        print(x.name)
     
        print(x.obj.name)
    Ce qui donne bien:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    testbis example
    test example
    Dans cet exemple, la ligne attribuant None à testbis.obj est bien facultative?


    Merci à tous pour vos réponses en tout cas, je pense avoir à peu près compris.
    Je marque le sujet comme "résolu".

  6. #6
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    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 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par vmonteco Voir le message
    Dans cet exemple, la ligne attribuant None à testbis.obj est bien facultative?
    Oui, mais c'est plutôt une question de discipline de codage et de facilité de lecture. Je n'aime pas beaucoup que Python accepte la création d'un nouvel attribut d'une classe à partir d'une instruction externe, alors je crée d'avance l'attribut en question avec une valeur None. Cela permet aussi, en relisant le code de la classe, d'avoir tous les attributs disponibles de cette classe.
    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

  7. #7
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2014
    Messages : 51
    Points : 44
    Points
    44
    Par défaut
    D'accord, je comprends ça.
    Merci!

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

Discussions similaires

  1. Petite question sur le typage des fonctions
    Par Dim Me As New Idiot dans le forum F#
    Réponses: 4
    Dernier message: 13/07/2010, 10h41
  2. Petite question sur la gestion des exception
    Par Wizard50 dans le forum C#
    Réponses: 1
    Dernier message: 05/05/2010, 09h17
  3. une petite question sur la texture des images
    Par katicr2 dans le forum Traitement d'images
    Réponses: 7
    Dernier message: 03/02/2010, 15h24
  4. petite question sur le format des dates
    Par sherdogvdb dans le forum Forms
    Réponses: 4
    Dernier message: 08/03/2007, 10h14

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