简体   繁体   中英

Order of execution with python class

I was writing a small python script to understand a concept and got another confusion. Here's the code -

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)

The output is -

Middle 5 3
Out 5 3
In 1 2 1 2

Now, my concept was python interpreter starts reading and executing the code from the first line to last line. It executes the code inside a class only when it is "called", not when it is defined. So, the output should print "Out" first. But here it is printing "Middle" first. This should not happen, as python interpreter when first encounters "Middle" - it is within the definition, and thus should not be executed at that time. It should be executed only after reading the last line of code where the class "Exp" is called.

I searched on Google and StackOverflow for the solution but couldn't find one explaining it for the class.

Kindly help me understand where I'm getting it wrong...

Your doubt is right. I had the same doubt like 6 months back and a friend of mine helped me figure the answer out.

print("Middle",x,y)

The above statement does not belong to any method. It belongs to the class Exp . The __init__() method is executed when an object is created and is internally called by the Python interpreter when an object is instantiated from your end. Since the above statement is not a part of any method, the interpreter executes it before invoking the __init__ method. Since variables x and y are both available in the scope of class Exp , it isn't considered an error and the interpreter executes it.

If you remove the declarations of variables x and y , you will see a NameError like below.

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

And this is because x and y are not even created from the class Exp 's perspective.

This odd behaviour happens because your print("Middle",x,y) is not inside a definition of a function, so it gets called before print("Out",x,y) .

Your code is equivalent to:

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)

Whose output will be:

Middle 5 3
Out 5 3
In 1 2 1 2

One of the possible ways to correct this is to define print("Middle",x,y) , say within the constructor.

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)

The output you will then get is:

Out 5 3
In 1 2 1 2
Middle 1 2

Class methods are not executed as compiled, they have to be invoked.

With your code above the print(middle) statement is not defined within a class method. Whereas the print(In) statement is defined within the init (also called constructor) method.

When you run the code and the compiler runs through the script, the print(In) statement is not invoked until the init () method is called.

However this print(middle) line is not defined as a method of the Exp class, but is executable as a built-in function, despite the whitespace. Consequently as Python compiles the class Exp the print(middle) statement is invoked. This is the only time the print(middle) statement would be invoked. As it is not in a class method it cannot be accessed later in the program.

If you try the code below, you get the output 'Out' and 'In'. You would only get 'Middle' by calling 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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM