2008-10-28 61 views
39

我覺得我應該知道這一點,但我一直無法弄清楚它...如何從Python函數或方法中獲取函數或方法的名稱?

我想從一個方法的名稱 - 這恰好是一個集成測試 - 從裏面所以它可以打印出一些診斷文本。當然,我可以在字符串中硬編碼該方法的名稱,但如果可能的話,我想讓測試更加乾燥。

+0

[如何獲取函數名稱作爲字符串在Python?](http://stackoverflow.com/questions/251464/how-to-get-the-function-name-as-string-in- python) – DarenW 2012-12-28 18:56:51

+0

@DarenW不是。從包含函數對象的變量請求函數的名稱並從內部請求函數的名稱是兩個截然不同的問題。 – 2016-02-12 15:27:05

回答

23

通過inspect之類涉及反省的答案是合理的。但可能有其他選擇,具體取決於您的情況:

如果您的集成測試是使用unittest模塊編寫的,那麼您可以在TestCase中使用self.id()

3

我認爲traceback模塊可能有你在找什麼。特別是,extract_stack函數看起來好像會完成這項工作。

16

這個裝飾器通過將函數作爲關鍵字參數傳遞來使方法的名稱可用。

from functools import wraps 
def pass_func_name(func): 
    "Name of decorated function will be passed as keyword arg _func_name" 
    @wraps(func) 
    def _pass_name(*args, **kwds): 
     kwds['_func_name'] = func.func_name 
     return func(*args, **kwds) 
    return _pass_name 

你會使用這種方式:

@pass_func_name 
def sum(a, b, _func_name): 
    print "running function %s" % _func_name 
    return a + b 

print sum(2, 4) 

但也許你會想要寫要直接裝飾本身裏面是什麼。然後代碼就是一個獲取裝飾器中函數名的方法的例子。如果你提供了關於你想在函數中做什麼的更多細節,那需要這個名字,也許我可以建議一些其他的東西。

+2

關於使用裝飾器而不是依賴實現細節 – 2008-10-29 04:07:00

+1

@MatthewTrevor說實話,我看到一個依靠實現細節的裝飾器。根據http://stackoverflow.com/questions/251464/how-to-get-a-function-name-as-a-string-in-python它應該是更好的使用`.__ name__`'.func_name` 。不過,我同意這個基本概念。 – 2016-02-12 15:29:54

53

這似乎是使用模塊inspect最簡單的方法:

import inspect 
def somefunc(a,b,c): 
    print "My name is: %s" % inspect.stack()[0][3] 

你可以用這個概括:

def funcname(): 
    return inspect.stack()[1][3] 

def somefunc(a,b,c): 
    print "My name is: %s" % funcname() 

感謝Stefaan Lippens這是通過谷歌找到。

10
# file "foo.py" 
import sys 
import os 

def LINE(back = 0): 
    return sys._getframe(back + 1).f_lineno 
def FILE(back = 0): 
    return sys._getframe(back + 1).f_code.co_filename 
def FUNC(back = 0): 
    return sys._getframe(back + 1).f_code.co_name 
def WHERE(back = 0): 
    frame = sys._getframe(back + 1) 
    return "%s/%s %s()" % (os.path.basename(frame.f_code.co_filename),  
          frame.f_lineno, frame.f_code.co_name) 

def testit(): 
    print "Here in %s, file %s, line %s" % (FUNC(), FILE(), LINE()) 
    print "WHERE says '%s'" % WHERE() 

testit() 

輸出:

$ python foo.py 
Here in testit, file foo.py, line 17 
WHERE says 'foo.py/18 testit()' 

使用「回= 1」中找到關於兩級回落堆棧信息等