2012-08-03 34 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_code情報については、f_locals属性に特定の地元の人々のために見ることになります:あなたは、各フレームで見つけた情報の種類を検出するために、いくつかの世話をする必要があります

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

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

のすべての実装に存在することが保証されていません、ありがとうございました私はこれを受け取り、それを私のニーズに適応させることができました。 –

2

おかげで、私はすべての呼び出し元の順序付けられたリストを返す関数を作ることができた答え:

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) 
関連する問題