2012-08-03 35 views
7

我想獲取有關python中特定函數的調用者的信息。例如:在python中獲取函數調用者的信息

class SomeClass(): 
    def __init__(self, x): 
     self.x = x 
    def caller(self): 
     return special_func(self.x) 

def special_func(x): 
    print "My caller is the 'caller' function in an 'SomeClass' class." 

python有可能嗎?

回答

10

是的,sys._getframe()函數讓您從當前執行堆棧中檢索幀,然後您可以使用inspect module中的方法和文檔檢查幀;您將在f_locals屬性來尋找特定的當地人,以及爲f_code信息:

import sys 
def special_func(x): 
    callingframe = sys._getframe(1) 
    print 'My caller is the %r function in a %r class' % (
     callingframe.f_code.co_name, 
     callingframe.f_locals['self'].__class__.__name__) 

請注意,你需要採取一些護理檢測到您在每幀中找到什麼樣的信息。

+2

從文檔:'它不能保證在Python.' – pradyunsg 2013-09-26 06:04:54

3

一個例子:

def f1(a): 
    import inspect 
    print 'I am f1 and was called by', inspect.currentframe().f_back.f_code.co_name 
    return a 

def f2(a): 
    return f1(a) 

將檢索 「立竿見影」 的來電者。

>>> f2(1) 
I am f1 and was called by f2 

如果不是從另一個叫你(在IDLE):

>>> f1(1) 
I am f1 and was called by <module> 
+0

的所有實現存在謝謝,我能夠接受並適應我的需求。 – 2014-01-29 20:37:32

2

由於喬恩Clements的答案,我是能夠使返回所有呼叫者的有序列表的功能:

def f1(): 
    names = [] 
    frame = inspect.currentframe() 
    ## Keep moving to next outer frame 
    while True: 
     try: 
      frame = frame.f_back 
      name = frame.f_code.co_name 
      names.append(name) 
     except: 
      break 
    return names 

並且當調用一個鏈:

def f2(): 
    return f1() 

def f3(): 
    return f2() 

def f4(): 
    return f3() 

print f4() 

看起來是這樣的:

['f2', 'f3', 'f4', '<module>'] 

在我來說,我在'<module>'和後過濾掉任何東西,然後拿最後一個項目是主叫方的姓名。

或修改原始循環的任何名稱的第一次亮相保釋開始'<'

frame = frame.f_back 
name = frame.f_code.co_name 
if name[0] == '<': 
    break 
names.append(name)