Why does inspect return different line for class inheriting from superclass?

不羁的心 提交于 2019-12-05 09:37:07

Further experiment shows that this is a quirk of Python's line number assignment. Particularly, if we use dis to see the disassembly of code with and without a base class:

import dis
import sys

dis.dis(sys._getframe().f_code)

def dec(): pass

@dec
class Foo: pass

@dec
class Bar(Foo): pass

We see that for Foo, the instructions involved have line number 8 (corresponding to the @dec line):

  8          58 LOAD_NAME                4 (dec)
             61 LOAD_BUILD_CLASS
             62 LOAD_CONST               4 (<code object Foo at 0x2b2a65422810, file "./prog.py", line 8>)
             65 LOAD_CONST               5 ('Foo')
             68 MAKE_FUNCTION            0
             71 LOAD_CONST               5 ('Foo')
             74 CALL_FUNCTION            2 (2 positional, 0 keyword pair)
             77 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             80 STORE_NAME               5 (Foo)

But for Bar, the line number advances from 11 to 12 for the LOAD_NAME that loads the base class:

 11          83 LOAD_NAME                4 (dec)
             86 LOAD_BUILD_CLASS
             87 LOAD_CONST               6 (<code object Bar at 0x2b2a654a0f60, file "./prog.py", line 11>)
             90 LOAD_CONST               7 ('Bar')
             93 MAKE_FUNCTION            0
             96 LOAD_CONST               7 ('Bar')

 12          99 LOAD_NAME                5 (Foo)
            102 CALL_FUNCTION            3 (3 positional, 0 keyword pair)
            105 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
            108 STORE_NAME               6 (Bar)

With no base class, the parent frame's f_lineno is on the @ line when the decorator runs. With a base class, the parent frame is on the load-the-base-class line.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!