python类的执行顺序

python类的执行顺序,python,class,interpreter,order-of-execution,Python,Class,Interpreter,Order Of Execution,我当时正在编写一个小python脚本来理解一个概念,但又遇到了另一个困惑。这是密码- 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) 输出为- Middle

我当时正在编写一个小python脚本来理解一个概念,但又遇到了另一个困惑。这是密码-

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)
输出为-

Middle 5 3
Out 5 3
In 1 2 1 2
现在,我的概念是python解释器开始从第一行到最后一行读取和执行代码。它仅在“调用”时,而不是在定义时,才在类内部执行代码。因此,输出应该首先打印“Out”。但在这里,它首先打印“中间”。这不应该发生,因为python解释器在第一次遇到“Middle”时——它在定义中,因此不应该在那个时候执行。它应该仅在读取调用类“Exp”的最后一行代码后执行

我在Google和StackOverflow上搜索了这个解决方案,但找不到一个能解释这个问题的解决方案


请帮助我理解我哪里弄错了…

类方法不是按编译方式执行的,它们必须被调用

对于上面的代码,print(middle)语句不是在类方法中定义的。而print(In)语句是在init(也称为构造函数)方法中定义的

当您运行代码并且编译器在脚本中运行时,在调用init()方法之前,不会调用print(In)语句

但是,此打印(中间)行未定义为Exp类的方法,而是作为内置函数可执行,尽管有空格。因此,在Python编译类Exp时,将调用print(middle)语句。这是唯一一次调用print(middle)语句。由于它不在类方法中,因此以后无法在程序中访问它

如果您尝试下面的代码,您将得到输出“Out”和“In”。通过调用Exp.test()只能得到“Middle”


发生这种奇怪的行为是因为
print(“Middle”,x,y)
不在函数的定义内,所以它在
print(“Out”,x,y)
之前被调用

您的代码相当于:

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)
其输出将是:

Middle 5 3
Out 5 3
In 1 2 1 2
纠正这种情况的一种可能方法是定义
print(“Middle”,x,y)
,比如在构造函数中

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)
您将获得的输出是:

Out 5 3
In 1 2 1 2
Middle 1 2

你的怀疑是对的。6个月前我也有同样的疑问,我的一个朋友帮我找到了答案

打印(“中间”,x,y)
上述声明不属于任何方法。它属于类
Exp
\uuuu init\uuuu()
方法是在创建对象时执行的,当从您的终端实例化对象时,Python解释器会在内部调用该方法。因为上面的语句不是任何方法的一部分,所以解释器在调用
\uuuu init\uuu
方法之前执行它。由于变量
x
y
都在类
Exp
的范围内可用,因此它不被视为错误,解释器执行它

如果删除变量
x
y
的声明,您将看到一个
namererror
,如下所示

回溯(最近一次呼叫最后一次):
文件“trial.py”,第9行,在
打印(“中间”,x,y)
名称错误:未定义名称“x”

这是因为
x
y
甚至都不是从类
Exp
的角度创建的。

不,类“定义”是在遇到时“执行”的。我想你在考虑函数和方法。检查我下面的答案,寻找一种正确的定义方法。明白了@夸姆拉纳。非常感谢。这回答了你的问题吗?你怎么知道这是“问题”?@quamrana这不是“问题”?OP的代码是完全有效的python。因此,“问题”或“问题”只是OP对结果感到惊讶。您已经提供了同样是完全有效的python代码,但它做了其他事情。我认为OP希望在执行过程中的某个时刻打印
中间
。对于您的代码,您必须添加其他内容才能调用
test()
@quamrana是的,您是正确的。我已相应地编辑了我的答案。您如何知道这是正确的行为?请重新编写我的答案以避免混淆!
Out 5 3
In 1 2 1 2
Middle 1 2