Python类的执行顺序

4
我正在编写一个小的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”。但是这里先打印了“Middle”。这不应该发生,因为当Python解释器第一次遇到“Middle”时 - 它在定义内部,因此此时不应该执行它。只有在读取代码的最后一行调用类“Exp”之后才应该执行它。
我在Google和StackOverflow上搜索了解决方案,但没有找到一个针对类的解释。
请帮助我理解我错在哪里...

5
不,类别中的“定义”会在遇到它们时“执行”。我认为你在考虑函数和方法。 - quamrana
请检查我下面给出的定义方式,看是否正确。 - Devesh Kumar Singh
好的... @quamrana。非常感谢您。 - Arnb
这回答解决了您的问题吗?【为什么类的主体在定义时被执行?】(https://dev59.com/aF8e5IYBdhLWcg3wAWjs) - wjandrea
3个回答

3

你的疑惑是正确的。我六个月前也有同样的疑问,我的一位朋友帮助我找到了答案。

print("Middle",x,y)

上述语句不属于任何方法,而是属于类Exp。当对象被创建时,将执行__init__()方法,并由Python解释器在您实例化对象时内部调用。由于上述语句不是任何方法的一部分,解释器在调用__init__方法之前执行它。由于变量xy都在类Exp的范围内,因此不会出现错误,解释器将其执行。

如果删除变量xy的声明,则会看到类似下面的NameError

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

这是因为在类Exp的角度下,xy甚至没有被创建。

2
这种奇怪的行为发生是因为你的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)。请注意,此处的“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)

你将获得的输出为:

最初的回答


Out 5 3
In 1 2 1 2
Middle 1 2

2
你怎么知道这是正确的行为? - quamrana
重新措辞我的答案以避免混淆! - Devesh Kumar Singh

0

类方法不会在编译时执行,必须调用才能执行。

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

当您运行代码并且编译器运行脚本时,print(In)语句直到调用init()方法才被调用。

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

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

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)

1
你怎么知道这是“问题”? - quamrana
@quamrana 这不是“问题”吗? - Andy
1
OP所拥有的代码是完全有效的Python代码。因此,“问题”或“问题”只是OP对结果感到惊讶。您提供的代码也是完全有效的Python代码,但它执行了其他操作。我认为OP 希望在执行过程中某个时刻打印出Middle。使用您的代码,您需要添加其他内容才能调用test() - quamrana
@quamrana 是的,你说得对。我已经相应地编辑了我的答案。 - Andy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接