首页 > 解决方案 > 尽管我没有创建类的实例,但为什么要从类中打印(x)?

问题描述

x = 5


class A:
    x += 1  # here we can access and change the value of x in class but only for class
    print(f"x from inside class is {x}")


print(x)

为什么在类中打印虽然我没有从类 A 中创建实例

标签: pythonoop

解决方案


Python 代码从上到下执行。该语句触发创建一个新的类对象,当达到 unindent 时class A,该对象将被最终确定并分配给全局名称。A

通过在单独的隔离命名空间中运行类主体中的所有语句来创建一个。一旦类主体完成执行,命名空间就被包装到一个类对象中。结果可以由metaclass预处理,但仅此而已。

该语句x += 1大致相当于x = x.__iadd__(1). 扩充的赋值发生在类命名空间内。它不会影响全局名称x,因为赋值发生在类命名空间中并且整数是不可变的。不变性很重要,因为该x赋值右侧的 来自全局命名空间,即使左侧不是。

像列表这样的可变对象会以不同的方式工作。Ifx是一个列表,x += [1]会将 的结果重新分配x.__iadd__([1])给一个类变量x,就像整数情况一样。但是,该操作__iadd__会就地修改列表对象。这意味着全局xA.x将引用相同的扩展列表。

class语句,就像语句一样,def是赋值操作。你告诉解释器运行一个初始化你的类的代码片段。这与 不同def,后者不运行您编写的任何代码行,而是将它们编译成函数对象。

当解释器创建类命名空间时,您会看到打印输出。该类以一个名为xset to的变量结束6。如果你有def语句,那么类命名空间中也会有函数。如果您尝试通过类的实例访问这些函数,它们将被绑定为方法,因为函数对象是非数据描述符


推荐阅读