Python 3注释的代码生成,默认值为

时间:2017-06-04 22:59:23

标签: python-3.x bytecode cpython disassembly

在处理uncompyle6反编译错误时,我遇到了问题 尝试协调CPython程序集输出与Python 文档描述了MAKE_FUNCTION

Python来源:

def foo(x: 'an argument that defaults to 5' = 5):
    return

Disassemby(xdis' s版本):

 # Argument count:    1
 # Kw-only arguments: 0
 # Number of locals:  1
 # Stack size:        1
 # Flags:             0x00000043 (NOFREE | NEWLOCALS | OPTIMIZED)
 # First Line:        1
 # Constants:
 #    0: 5
 #    1: 'an argument that defaults to 5'
 #    2: ('x',)
 #    3: <code object foo at 0x7f49115938a0, file "exec", line 1>
 #    4: 'foo'
 #    5: None
 # Names:
 #    0: foo
 1 0 LOAD_CONST                0 (5)
   3 LOAD_CONST                1 ('an argument that defaults to 5')
   6 LOAD_CONST                2 (('x',))
   9 LOAD_CONST                3 (<code object foo at 0x7f49115938a0, file "exec", line 1>)
  12 LOAD_CONST                4 ('foo')
  15 EXTENDED_ARG              2 (131072)
  18 MAKE_FUNCTION        131073 (1 positional, 0 name and default, 2 annotations)
  21 STORE_NAME                0 (foo)
  24 LOAD_CONST                5 (None)
  27 RETURN_VALUE

请注意,在偏移量18中,该值基本上是偏移量19(1)处的arg值加上扩展的arg值。

括号中的解释是xdis,可能不正确。 编辑:不仅正确,而且偏移6中的附加对表示元组是必不可少的。

https://docs.python.org/3.4/library/dis.html#opcode-MAKE_FUNCTION中说:

  

在堆栈上推送新的函数对象。从下到上,消耗的堆栈必须由

组成      
      
  • argc&amp; 0xFF默认参数对象的位置顺序
  •   
  • (argc&gt;&gt; 8)&amp; 0xFF对名称和默认参数,名称恰好在堆栈上的对象下方,仅用于关键字参数
  •   
  • (argc&gt;&gt; 16)&amp; 0x7FFF参数注释对象
  •   
  • 列出注释的参数名称的元组(仅当存在任何注释对象时)
  •   

在我看来,有一个注释对象,而不是两个。一个默认参数而不是位置参数。也 在第24位我们看到提到5,但这是在我们之后 MAKE_FUNCTION。默认值与参数x的关联在代码中是难以捉摸的。这里有一些优化吗?

我如何理解程序集作为Python源代码的准确表示?

注意:我看到这个代码至少在Python 3.1 - 3.5

中生成

1 个答案:

答案 0 :(得分:1)

以下是uncompyle6的上述内容。我并不完全确定mkfunc_annotate的第一个参数被正确地称为pos_arg而不是默认值arg是正确的。

上面程序集中的一个细微点是LOAD_CONST是一个元组(带有一个参数),这对于解析一个deparser(或者人)是很重要的,因为该函数是注释的。

stmts
    sstmt
        stmt
            funcdef_annotate (2)
                 0. mkfunc_annotate (7)
                     0. pos_arg
                        expr
                            L.   1       0  LOAD_CONST            5  5
                     1. annotate_arg
                        expr
                                         3  LOAD_CONST               'an argument that defaults to 5'
                     2. annotate_tuple
                                     6  LOAD_CONST               ('x',)
                     3.              9  LOAD_CONST               '<code_object foo>'
                     4.             12  LOAD_CONST               'foo'
                     5.             15  EXTENDED_ARG     131074  '131072'
                     6.             18  MAKE_FUNCTION_A_2_1        '1 positional, 0 keyword pair, 2 annotated'
                 1. designator
                                21  STORE_NAME               'foo'