[python]能知道函数的外层调用函数吗?

2015-05-21 10:28:10 +08:00
 zerh925
def foo():
    print 'foo'

def bar():
    foo()

def run():
    foo()

我有办法知道知道foo()每次是被什么函数调用吗?

比如被bar()调用和被run()调用做不同的操作。

或者我能知道foo()每次被调用是程序运行以来第几次运行吗?自省能做到这些吗?

3022 次点击
所在节点    Python
17 条回复
Septembers
2015-05-21 10:32:07 +08:00
不能
(理论可以通过动态分析bytecode完成(恩 我没测试过
arbipher
2015-05-21 10:34:55 +08:00
被什么函数调用可以知道,参考
https://docs.python.org/2/library/inspect.html
http://stackoverflow.com/questions/900392/getting-the-caller-function-name-inside-another-function-in-python

第几次被调用据我所知没有,等大神来回答吧。你加个count或者用闭包试试。
vicalloy
2015-05-21 10:36:20 +08:00
我觉得你还是给foo加个参数吧
zerh925
2015-05-21 10:36:39 +08:00
刚dir了一下任意函数,发现一个func_name属性。通过传这个参数给foo()算是实现了。
```python
def foo(outer):
print "I was called by ", outer

def bar():
foo(bar.func_name)

def run():
foo(run.func_name)
```

还有更好的办法吗?
9hills
2015-05-21 10:37:51 +08:00
https://gist.github.com/ninehills/9917858

不仅能知道是谁调用的,还会打印出调用链。debug用
zerh925
2015-05-21 10:38:20 +08:00
@arbipher 感谢!非常有用!刚在打自己的答案
9hills
2015-05-21 10:38:42 +08:00
效果如下:
$ python test.py
2014-04-02 00:40:44,273 [test.py:main() --> test.py:test('aaa')] hahha aaa
muzuiget
2015-05-21 10:39:50 +08:00
可以的,用这个模块 https://docs.python.org/2/library/traceback.html

我最常用的

import traceback; traceback.print_stack()

打印当前的调用栈,其实就是相当于出现错误时的信息。
songco
2015-05-21 12:25:18 +08:00
支持stacktrace的都可以把...
recall704
2015-05-21 13:20:48 +08:00
就二楼哪个方法吧,之前也是用的那个方式.
alexapollo
2015-05-21 14:24:15 +08:00
每个语言的月经贴。记住关键字:stacktrace/backtrace,加上语言python/c/java,google一搜就有。

授人以渔!
monkeylyf
2015-05-21 15:10:46 +08:00
>>> import inspect
>>> inspect.stack()
staticor
2015-05-21 15:52:01 +08:00
我以前在leetcode还是codewars好像见过类似的统计函数被第几次调用的 提供一个可能有帮助的代码

![](http://7xivqr.com1.z0.glb.clouddn.com/15-5-21/88924102.jpg)
staticor
2015-05-21 15:57:54 +08:00
WKPlus
2015-05-21 18:17:53 +08:00
查找caller上面很多人说过了,我用过一个方法来统计这个函数被调用多少次:

def foo(called=[0]):
called[0] += 1 # called[0]记录了foo被调用了多少次
#your code here


总算发现了python函数default值这个坑的第二个用法了:)

当然也可以用函数属性来完成这个工作,不过要在foo函数定义之外再初始化一次这个属性,感觉没上面的代码好玩~
zerh925
2015-05-22 06:29:03 +08:00
@WKPlus nice trick!
jedihy
2015-05-22 08:53:18 +08:00
几乎所有语言都能打调用栈啊

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/192636

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX