[python] 해당 함수 내에서 함수 이름 결정 (트레이스 백을 사용하지 않고)

파이썬에서는 traceback모듈 을 사용하지 않고 해당 함수 내에서 함수 이름을 결정하는 방법이 있습니까?

기능 표시 줄이있는 foo 모듈이 있다고 가정 해보십시오. 를 실행할 때 foo.bar()bar가 bar의 이름을 알 수있는 방법이 있습니까? 아니면 더 나은 foo.bar이름입니까?

#foo.py  
def bar():
    print "my name is", __myname__ # <== how do I calculate this at runtime?



답변

파이썬에는 함수 자체 내에서 함수 또는 그 이름에 액세스하는 기능이 없습니다. 제안 되었지만 거부 되었습니다 . 스택을 직접 사용하고 싶지 않은 경우 컨텍스트에 따라 사용 "bar"하거나 사용해야합니다 bar.__name__.

주어진 거부 통지는 다음과 같습니다.

이 PEP는 거부됩니다. 어떻게 구현해야하는지 또는 정확한 경우 의미론이 무엇인지 명확하지 않으며, 중요한 사용 사례가 충분하지 않습니다. 응답은 기껏해야 미지근했습니다.


답변

import inspect

def foo():
   print(inspect.stack()[0][3])
   print(inspect.stack()[1][3]) #will give the caller of foos name, if something called foo


답변

동일한 결과를 얻는 몇 가지 방법이 있습니다.

from __future__ import print_function
import sys
import inspect

def what_is_my_name():
    print(inspect.stack()[0][0].f_code.co_name)
    print(inspect.stack()[0][3])
    print(inspect.currentframe().f_code.co_name)
    print(sys._getframe().f_code.co_name)

inspect.stack통화는 다른 통화보다 수천 배 느립니다.

$ python -m timeit -s 'import inspect, sys' 'inspect.stack()[0][0].f_code.co_name'
1000 loops, best of 3: 499 usec per loop
$ python -m timeit -s 'import inspect, sys' 'inspect.stack()[0][3]'
1000 loops, best of 3: 497 usec per loop
$ python -m timeit -s 'import inspect, sys' 'inspect.currentframe().f_code.co_name'
10000000 loops, best of 3: 0.1 usec per loop
$ python -m timeit -s 'import inspect, sys' 'sys._getframe().f_code.co_name'
10000000 loops, best of 3: 0.135 usec per loop


답변

@Andreas Jung이 보여주는 접근 방식을 사용하여 정의 된 이름을 얻을 수 있지만 함수가 호출 된 이름이 아닐 수도 있습니다.

import inspect

def Foo():
   print inspect.stack()[0][3]

Foo2 = Foo

>>> Foo()
Foo

>>> Foo2()
Foo

그 구별이 당신에게 중요한지 아닌지는 말할 수 없습니다.


답변

functionNameAsString = sys._getframe().f_code.co_name

함수 이름을 코드의 여러 위치에있는 로그 문자열에 넣고 싶었 기 때문에 매우 비슷한 것을 원했습니다. 아마도 가장 좋은 방법은 아니지만 현재 함수의 이름을 얻는 방법이 있습니다.


답변

이 편리한 유틸리티를 근처에 둡니다.

import inspect
myself = lambda: inspect.stack()[1][3]

용법:

myself()


답변

inspect가장 좋은 방법 이라고 생각 합니다. 예를 들면 다음과 같습니다.

import inspect
def bar():
    print("My name is", inspect.stack()[0][3])