2
votes

Ordre d'exécution avec la classe python

J'écrivais un petit script python pour comprendre un concept et j'ai eu une autre confusion. Voici le code -

Middle 5 3
Out 5 3
In 1 2 1 2

Le résultat est -

x = 5
y = 3

class Exp(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

        print("In",x, y, self.x, self.y)
    print("Middle",x,y)

print("Out",x,y)

Exp(1,2)

Maintenant, mon concept était que l'interpréteur python commence à lire et à exécuter le code à partir du premier ligne à la dernière ligne. Il n'exécute le code à l'intérieur d'une classe que lorsqu'il est "appelé", pas lorsqu'il est défini. Ainsi, la sortie doit d'abord imprimer «Out». Mais ici, il imprime d'abord "Milieu". Cela ne devrait pas arriver, en tant qu'interpréteur python lors de la première rencontre avec "Middle" - cela fait partie de la définition, et ne devrait donc pas être exécuté à ce moment-là. Il ne doit être exécuté qu'après avoir lu la dernière ligne de code où la classe "Exp" est appelée.

J'ai recherché la solution sur Google et StackOverflow mais je n'ai pas trouvé de solution expliquant la classe.

Veuillez m'aider à comprendre où je me trompe ...


4 commentaires

Non, les «définitions» de classe sont «exécutées» lorsqu'elles sont rencontrées. Je pense que vous pensez aux fonctions et aux méthodes.


Vérifiez ma réponse ci-dessous pour une possible manière correcte de définir.


Compris ... @quamrana. Merci beaucoup.


Est-ce que cela répond à votre question? Pourquoi le corps d'une classe est-il exécuté au moment de la définition?


3 Réponses :


0
votes

Les méthodes de classe ne sont pas exécutées telles qu'elles sont compilées, elles doivent être appelées.

Avec votre code au-dessus, l'instruction print (middle) n'est pas définie dans une méthode de classe. Alors que l'instruction print (In) est définie dans la méthode init (également appelée constructeur).

Lorsque vous exécutez le code et que le compilateur exécute le script, l'impression (In ) n'est pas appelée tant que la méthode init () n'est pas appelée.

Cependant, cette ligne d'impression (du milieu) n'est pas définie comme une méthode de la classe Exp, mais est exécutable comme une fonction intégrée, malgré les espaces. Par conséquent, lorsque Python compile la classe Exp, l'instruction print (middle) est appelée. C'est la seule fois où l'instruction print (middle) est appelée. Comme il n'est pas dans une méthode de classe, il ne sera pas accessible plus tard dans le programme.

Si vous essayez le code ci-dessous, vous obtenez la sortie 'Out' et 'In'. Vous n'obtiendrez "Middle" qu'en appelant Exp.test ()

x = 5
y = 3

class Exp(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

        print("In",x, y, self.x, self.y)

    def test(self):
        print("Middle",x,y)  

print("Out",x,y)

Exp(1,2)


4 commentaires

Comment savez-vous que c'est le «problème»?


@quamrana n'est-ce pas le «problème»?


Le code que l'OP a est un python parfaitement valide. Le «problème», ou «problème», c'est donc simplement que le PO est surpris du résultat. Vous avez présenté du code qui est également parfaitement valide en python, mais il fait autre chose. Je pense que l'OP voulait que Middle soit imprimé à un moment donné pendant l'exécution. Avec votre code, vous devrez ajouter quelque chose d'autre pour appeler test () .


@quamrana Oui, vous avez raison. J'ai modifié ma réponse en conséquence.



2
votes

Ce comportement étrange se produit parce que votre print ("Middle", x, y) n'est pas à l'intérieur d'une définition de fonction, donc il est appelé avant print ("Out", x , y) .

Votre code équivaut à:

Out 5 3
In 1 2 1 2
Middle 1 2

Dont la sortie sera:

x = 5
y = 3

class Exp(object):

    def __init__(self, x, y):
        self.x = x
        self.y = y

        print("In",x, y, self.x, self.y)
        print("Middle",x,y)

print("Out",x,y) 
Exp(1,2)

L'un des moyens possibles de corriger cela est de définir print ("Middle", x, y) , par exemple dans le constructeur.

Middle 5 3
Out 5 3
In 1 2 1 2

Le résultat que vous obtiendrez alors est:

x = 5
y = 3

class Exp(object):

    def __init__(self, x, y):
        self.x = x
        self.y = y

        print("In",x, y, self.x, self.y)

print("Middle",x,y)
print("Out",x,y) 
Exp(1,2)


2 commentaires

Comment savez-vous que c'est le bon comportement?


Reformulé ma réponse pour éviter toute confusion!



2
votes

Votre doute est juste. J'ai eu le même doute il y a 6 mois et un de mes amis m'a aidé à trouver la réponse.

Traceback (most recent call last):
  File "trial.py", line 9, in <module>
    print("Middle",x,y)
NameError: name 'x' is not defined

La déclaration ci-dessus n'appartient à aucune méthode. Il appartient à la classe Exp . La méthode __init __ () est exécutée lorsqu'un objet est créé et est appelée en interne par l'interpréteur Python lorsqu'un objet est instancié depuis votre extrémité. Puisque l'instruction ci-dessus ne fait partie d'aucune méthode, l'interpréteur l'exécute avant d'appeler la méthode __init__ . Puisque les variables x et y sont toutes deux disponibles dans le champ d'application de la classe Exp , cela n'est pas considéré comme une erreur et l'interpréteur l'exécute.

Si vous supprimez les déclarations des variables x et y , vous verrez une NameError comme ci-dessous.

print("Middle",x,y)

Et c'est parce que x et y ne sont même pas créés du point de vue de la classe Exp .


0 commentaires