2012-08-03 37 views
7

Python'da belirli bir işlevin arayanları hakkında bilgi almak istiyorum. Örneğin:Arayanın bilgilerini python işleviyle alın

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 ile mümkün mü?

cevap

10

Evet, sys._getframe() işlevi, geçerli yürütme kümesinden kareleri alabilmenizi sağlar; daha sonra inspect module; Eğer hem de f_code bilgi için f_locals özelliğinde belirli halk için bakmanız gerekir: Eğer her karede bulmak ne tür bilgiler tespit etmek için bazı dikkat çekmek gerekir

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__) 

Not.

+2

: 'Bu teşekkür ederiz Python.' – pradyunsg

3

Bir örnek:

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) 

"acil" arayan almak olacaktır. diğerinden çağrılmadı eğer

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

Ve (IDLE olarak) olsun: Bütün arayanlar sıralı bir listesini döndüren bir işlev yapmak başardı Jon Clements cevaba

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

tüm uygulamalarda mevcut garanti edilmez, Bunu alıp ihtiyaçlarıma adapte edebildim. –

2

Teşekkür:

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 

ve bir zincir çağrıldığında:

def f2(): 
    return f1() 

def f3(): 
    return f2() 

def f4(): 
    return f3() 

print f4() 

şuna benzer: Benim durumumda

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

Ben kaynak arayanın ismi olmaya son öğeyi almak sonra '<module>' de ve sonra herhangi bir şey filtrelemek ve.

Ya '<' ile başlayan herhangi bir isim görülmesiyle birlikte kefalet orijinal döngü değiştirin: Dokümanlar

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