当前位置: 首页 > 面试题库 >

为什么在定义时执行类的主体?

郎鸿雪
2023-03-14
问题内容

与函数相反,类的主体在定义时执行:

class A(object):
    print 'hello'

出:

hello

为什么会这样呢?它与@classmethod/@staticmethod方法和类属性有关吗?


问题答案:

*Python首次导入模块时, *所有操作 均在模块级别执行。函数体(和生成器表达体)在这里是 例外
,而不是规则。Python执行所有操作以创建模块中包含的 对象 ;像Python中的所有内容一样,类是对象,函数也是。

类主体使用单独的代码对象的唯一原因是因为类主体是在单独的名称空间中执行的,然后该名称空间构成了类属性。类主体不是唯一的此类命名空间;set和dict理解,并且在Python
3中,列表理解也使用单独的命名空间执行,对本地变量进行范围界定。

因此,函数和生成器表达式是个例外,这是因为它们的全部 目的 将在以后执行。注意,该函数 的定义 执行:

>>> import dis
>>> dis.dis(compile('def foo(): pass', '<stdin>', 'exec'))
  1           0 LOAD_CONST               0 (<code object foo at 0x106aef2b0, file "<stdin>", line 1>)
              3 MAKE_FUNCTION            0
              6 STORE_NAME               0 (foo)
              9 LOAD_CONST               1 (None)
             12 RETURN_VALUE

MAKE_FUNCTION那里的字节码创建函数对象,以及该函数的存储字节码,结果绑定到全局名称foo

这里的类对象没有什么不同。该class语句产生一个类对象,作为该对象的一部分,我们需要从类主体中了解属性。

如果Python 执行类主体,则其他代码将无法使用这些类成员。您无法访问类属性(包括类方法和静态方法),无法 设置 类属性,等等。

当然,那时
执行属于类主体的任何功能。与顶级函数一样,仅MAKE_FUNCTION执行字节码,然后将所得的本地名称(设置为STORE_FAST)转换为类属性,类似于将全局函数对象绑定到带有的全局函数对象STORE_NAME



 类似资料:
  • 问题内容: 我刚刚遇到了这个“错误”,但是我不确定这是否是故意的:代码: 在第一个示例中,它是在swing线程上执行的,但在第二个示例中,它不是,尽管我认为应该这样做。 这是错误还是故意的? 问题答案: 在我看来,这似乎是您的误解 第一行就像在说:“好吧,秋千,我想要你做的是”。所以Swing执行它 第二行就像是说:“确定,Swing,我要您执行的是方法返回的对象的方法”。一个是方法, 我现在执行

  • 尝试将我的java应用程序从Eclipse导出到可运行的jar文件中。(这是一个控制台应用程序) 这是Eclipse中项目目录的外观: 以下是项目的运行配置: 这就是jar创建选项的外观: 最后,这是我得到的错误: 我真的试过了所有的东西,但我很困惑为什么它不运行。主类选择正确,运行配置似乎正确,我尝试了runnable和regular,两者都不起作用。 我尝试过清理、重建,甚至重新制作这个项目,

  • 在src/main/groovy/foo/test2.java中: 分级文件: 我造了一个罐子: 我在这里有版本控制中的测试用例: https://github.com/wu-lee/test-groovy-main

  • 据我所知,init block是一个在任何构造函数之前执行的块,每当该构造函数用于创建对象时。但是为什么规则在这里矛盾...... 这里,由于只形成了子类对象,那么为什么要调用父类的init块呢?

  • 问题内容: 我试图了解如何开发独立的Javascript代码。我想用命令行运行测试和模块编写Javscript代码。所以,我已经安装,并伴随着图书馆,和。 我的目录结构如下所示: 我在用下面的代码编写的一个小模块在哪里: 并且是测试: 然后,我尝试从顶级目录运行(因此看到该目录): 所以我的问题是: 这是构造代码的正确方法吗? 为什么我的测试无法运行? 学习这种东西的最好方法是什么?我很难在Goo

  • 变更集A:context=test 变更集B:没有上下文 变更集C:context=prod 所以 执行带有context=test的更新,将执行变更集A+B 执行带有context=prod的更新,将执行变更集B+C 在没有上下文的情况下执行更新,将执行变更集A+B+C 同样,我希望在更新执行时省略测试,只执行常规变更集,而不执行测试变更集。 或者我在这里漏掉了什么:)?