如何在被调用的方法中获得调用者的方法名?

假设我有两个方法:

def method1(self):
    ...
    a = A.method2()

def method2(self):
    ...

如果我不想为method1做任何改变,如何获得调用者的名字(在这个例子中,名字是method1)在method2?


当前回答

您可以使用装饰器,而不必使用stacktrace

如果您想在类中修饰一个方法

import functools

# outside ur class
def printOuterFunctionName(func):
@functools.wraps(func)
def wrapper(self):
    print(f'Function Name is: {func.__name__}')
    func(self)    
return wrapper 

class A:
  @printOuterFunctionName
  def foo():
    pass

你可以删除functools, self,如果它是过程性的

其他回答

上面的东西混合在一起。但这是我的尝试。

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

输出是

level :             module             : name
--------------------------------------------------
    3 :              None              : fizz
    2 :              None              : baz
    1 :              None              : bar
    0 :            __main__            : foo

嘿,伙计,我曾经为我的应用程序做了3个没有插件的方法,也许这可以帮助你,它对我有用,所以可能对你也有用。

def method_1(a=""):
    if a == "method_2":
        print("method_2")

    if a == "method_3":
        print("method_3")


def method_2():
    method_1("method_2")


def method_3():
    method_1("method_3")


method_2()

您可以使用装饰器,而不必使用stacktrace

如果您想在类中修饰一个方法

import functools

# outside ur class
def printOuterFunctionName(func):
@functools.wraps(func)
def wrapper(self):
    print(f'Function Name is: {func.__name__}')
    func(self)    
return wrapper 

class A:
  @printOuterFunctionName
  def foo():
    pass

你可以删除functools, self,如果它是过程性的

检查。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 sys
print sys._getframe().f_back.f_code.co_name