模块是否有代码对象属性?

时间:2018-01-30 15:07:06

标签: python

根据 explore to the code object

  

函数具有代码内部代码的代码对象属性,并且   代码对象具有字节码属性。通过执行字节码,   python执行函数代码。

  1. 模块对象也有所有的代码对象属性 代码里面?
  2. python是否通过执行来执行模块内部的代码 模块的代码对象的字节码属性。
  3. 如果没有,python在实例化时执行的操作是什么 我们import模块
  4. 时的模块对象

1 个答案:

答案 0 :(得分:1)

在CPython模块中,没有在运行时附加的代码对象。 *.pyc文件包含模块的字节码,但在import执行后会被丢弃,因为导入后不再需要它。

鉴于它是模块的第一次导入,运行时会检查是否存在最新的缓存字节码文件。如果有,则加载它,并在新的module对象的上下文中执行代码对象。如果没有,则将源编译为字节码,可能写入文件,并在新的module对象的上下文中执行。

那么如何获取模块的字节码呢?如果您有字节码文件,则可以从中解组字节码。假设我们有一个只包含print('Hello, World!')的模块:

>>> data = open('__pycache__/test.cpython-35.pyc', 'rb').read()
>>> import imp
>>> data.startswith(imp.get_magic())
True
>>> import marshal
>>> marshal.loads(data[len(imp.get_magic())+8:])
<code object <module> at 0x7f47b4fb5b70, file "/home/bj/test.py", line 4>
>>> import dis
>>> dis.dis(marshal.loads(data[len(imp.get_magic())+8:]))
  4           0 LOAD_NAME                0 (print)
              3 LOAD_CONST               0 ('Hello, World!')
              6 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
              9 POP_TOP
             10 LOAD_CONST               1 (None)
             13 RETURN_VALUE

如果您只有源代码:compile()

>>> compile("print('Hello, World!')", '<input>', 'exec')
<code object <module> at 0x7f47b4fc0f60, file "<input>", line 1>
>>> dis.dis(compile("print('Hello, World!')", '<input>', 'exec'))
  1           0 LOAD_NAME                0 (print)
              3 LOAD_CONST               0 ('Hello, World!')
              6 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
              9 POP_TOP
             10 LOAD_CONST               1 (None)
             13 RETURN_VALUE       13 RETURN_VALUE