호출 된 메소드에서 호출자의 메소드 이름을 얻는 방법은 무엇입니까?
파이썬 : 호출 된 메소드에서 호출자의 메소드 이름을 얻는 방법은 무엇입니까?
두 가지 방법이 있다고 가정합니다.
def method1(self):
...
a = A.method2()
def method2(self):
...
method1을 변경하지 않으려면 method2에서 호출자의 이름을 얻는 방법 (이 예제에서 이름은 method1입니다)?
inspect.getframeinfo 및 기타 관련 기능 inspect
이 도움 이 될 수 있습니다.
>>> import inspect
>>> def f1(): f2()
...
>>> def f2():
... curframe = inspect.currentframe()
... calframe = inspect.getouterframes(curframe, 2)
... print('caller name:', calframe[1][3])
...
>>> f1()
caller name: f1
이 내부 검사는 디버깅 및 개발을 돕기위한 것입니다. 생산 기능 목적으로 사용하는 것은 좋지 않습니다.
더 짧은 버전 :
import inspect
def f1(): f2()
def f2():
print 'caller name:', inspect.stack()[1][3]
f1()
(@Alex 및 Stefaan Lippen 덕분에 )
이것은 잘 작동하는 것 같습니다 :
import sys
print sys._getframe().f_back.f_code.co_name
모듈과 클래스를 포함한 전체 메소드 이름을 작성하려고 시도하는 약간 더 긴 버전을 생각해 냈습니다.
https://gist.github.com/2151727 (rev 9cccbf)
# Public Domain, i.e. feel free to copy/paste
# Considered a hack in Python 2
import inspect
def caller_name(skip=2):
"""Get a name of a caller in the format module.class.method
`skip` specifies how many levels of stack to skip while getting caller
name. skip=1 means "who calls me", skip=2 "who calls my caller" etc.
An empty string is returned if skipped levels exceed stack height
"""
stack = inspect.stack()
start = 0 + skip
if len(stack) < start + 1:
return ''
parentframe = stack[start][0]
name = []
module = inspect.getmodule(parentframe)
# `modname` can be None when frame is executed directly in console
# TODO(techtonik): consider using __main__
if module:
name.append(module.__name__)
# detect classname
if 'self' in parentframe.f_locals:
# I don't know any way to detect call from the object method
# XXX: there seems to be no way to detect static method call - it will
# be just a function call
name.append(parentframe.f_locals['self'].__class__.__name__)
codename = parentframe.f_code.co_name
if codename != '<module>': # top level usually
name.append( codename ) # function or a method
## Avoid circular refs and frame leaks
# https://docs.python.org/2.7/library/inspect.html#the-interpreter-stack
del parentframe, stack
return ".".join(name)
Bit of an amalgamation of the stuff above. But here's my crack at it.
def print_caller_name(stack_size=3):
def wrapper(fn):
def inner(*args, **kwargs):
import inspect
stack = inspect.stack()
modules = [(index, inspect.getmodule(stack[index][0]))
for index in reversed(range(1, stack_size))]
module_name_lengths = [len(module.__name__)
for _, module in modules]
s = '{index:>5} : {module:^%i} : {name}' % (max(module_name_lengths) + 4)
callers = ['',
s.format(index='level', module='module', name='name'),
'-' * 50]
for index, module in modules:
callers.append(s.format(index=index,
module=module.__name__,
name=stack[index][3]))
callers.append(s.format(index=0,
module=fn.__module__,
name=fn.__name__))
callers.append('')
print('\n'.join(callers))
fn(*args, **kwargs)
return inner
return wrapper
Use:
@print_caller_name(4)
def foo():
return 'foobar'
def bar():
return foo()
def baz():
return bar()
def fizz():
return baz()
fizz()
output is
level : module : name
--------------------------------------------------
3 : None : fizz
2 : None : baz
1 : None : bar
0 : __main__ : foo
I would use inspect.currentframe().f_back.f_code.co_name
. Its use hasn't been covered in any of the prior answers which are mainly of one of three types:
- Some use
inspect.stack
but it's known to be too slow. - Some use
sys._getframe
which is an internal private function given its leading underscore, and so its use is implicitly discouraged. - One uses
inspect.getouterframes(inspect.currentframe(), 2)[1][3]
but it's entirely unclear what[1][3]
is accessing.
import inspect
import types
from typing import cast
def caller_name() -> str:
"""Return the calling function's name."""
# Ref: https://stackoverflow.com/a/57712700/
return cast(types.FrameType, inspect.currentframe()).f_back.f_code.co_name
if __name__ == '__main__':
def _test_caller_name() -> None:
assert caller_name() == '_test_caller_name'
_test_caller_name()
Acknowlegement: prior comment by 1313e for an answer.
I found a way if you're going across classes and want the class the method belongs to AND the method. It takes a bit of extraction work but it makes its point. This works in Python 2.7.13.
import inspect, os
class ClassOne:
def method1(self):
classtwoObj.method2()
class ClassTwo:
def method2(self):
curframe = inspect.currentframe()
calframe = inspect.getouterframes(curframe, 4)
print '\nI was called from', calframe[1][3], \
'in', calframe[1][4][0][6: -2]
# create objects to access class methods
classoneObj = ClassOne()
classtwoObj = ClassTwo()
# start the program
os.system('cls')
classoneObj.method1()
#!/usr/bin/env python
import inspect
called=lambda: inspect.stack()[1][3]
def caller1():
print "inside: ",called()
def caller2():
print "inside: ",called()
if __name__=='__main__':
caller1()
caller2()
shahid@shahid-VirtualBox:~/Documents$ python test_func.py
inside: caller1
inside: caller2
shahid@shahid-VirtualBox:~/Documents$
you can print a list of function like answered here https://stackoverflow.com/a/56897183/4039061
import inspect;print(*['\n\x1b[0;36;1m| \x1b[0;32;1m{:25}\x1b[0;36;1m| \x1b[0;35;1m{}'.format(str(x.function), x.filename+'\x1b[0;31;1m:'+str(x.lineno)+'\x1b[0m') for x in inspect.stack()])
참고URL : https://stackoverflow.com/questions/2654113/how-to-get-the-callers-method-name-in-the-called-method
'IT박스' 카테고리의 다른 글
PHP 치명적 오류 : 정의되지 않은 함수 json_decode () 호출 (0) | 2020.06.06 |
---|---|
명령 행을 사용하여 파일을 압축 해제하는 방법은 무엇입니까? (0) | 2020.06.06 |
2 열 div 레이아웃 : 너비가 고정 된 오른쪽 열, 왼쪽 유체 (0) | 2020.06.06 |
동일한 테이블의 한 열에서 다른 열로 값 복사 (0) | 2020.06.06 |
@IBDesignable 오류 : IB Designables : 자동 레이아웃 상태를 업데이트하지 못했습니다 : 인터페이스 빌더 Cocoa Touch Tool이 충돌했습니다 (0) | 2020.06.05 |