Python 内省 - 如何在函数内部检查当前模块/调用行

6 投票
3 回答
1893 浏览
提问于 2025-04-16 13:49

我有一个函数:

# utils.py
def hello(name='World'):
    # Detect where I'm being called from.
    print('Hi, %s. You called this from %s at line # %d.' % (name, mod, lineno))
    # ``mod`` and ``lineno`` on previous line would have been set in real use.

我在其他地方导入这个函数并运行它

# other.py (this comment at line # 138)
from utils import hello
hello('Johnny')  # From inside ``hello`` I want to be able to detect that this
# was called from other.py at line # 140

3 个回答

1

使用warnings模块。

import warnings

def test(where):
    warnings.warn('hi from test', stacklevel=2)

def foo():
    test('inside foo')

test('from main module')
foo()

结果:

/tmp/test.py:9: UserWarning: hi from test
  test('from main module')
/tmp/test.py:7: UserWarning: hi from test
  test('inside foo')

查看行号。使用warnings模块非常好,因为你的模块的用户可以选择关闭警告,或者把它们变成可以详细检查的异常。

3

traceback模块可以帮助你提取调用栈,这样你就能看到是怎么一步步到达当前这个位置的。如果你愿意,还可以把调用这个函数的函数也打印出来,甚至可以一直往上追溯到更高的调用层级。

import traceback

def _trace():
    stack = traceback.extract_stack()[-3:-1]
    path, line, in_func, _instr = stack[0]
    print 'called from %s in func %s at line %s' % (path, in_func, line)

def bar():
    _trace()

def foo():
    bar()
    baz()

def baz():
    bar()

bar()
foo()

输出结果:

called from hello.py in func <module> at line 20
called from hello.py in func foo at line 14
called from hello.py in func baz at line 18
13

访问当前帧的外部框架,可以使用 inspect.currentframe() 这个方法:

import inspect

def hello(name='World'):
    f = inspect.currentframe().f_back
    mod = f.f_code.co_filename
    lineno = f.f_lineno
    print('Hi, %s. You called this from %s at line # %d.' %
          (name, mod, lineno))

撰写回答