如何打印动态分配函数的方法名称?

时间:2018-09-19 13:48:13

标签: python python-3.x function dynamic

当我运行以下代码时,仅方法中已动态分配给类“ Test”的print语句仅返回“ my_unique_method_name”。

如何打印我给定的方法名称?(方法中哪个是“ wizardry”,请参见下面的“ Expected Output”。)

#!/usr/bin/python3
import sys
import inspect

class Test:
    pass

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

Test.wizardry = my_unique_method_name
t = Test()
t.wizardry()

当前输出

my_unique_method_name
my_unique_method_name
my_unique_method_name

预期产量

wizardry

2 个答案:

答案 0 :(得分:0)

函数名称​​ 是“ my_unique_method_name”-该函数是一个对象,其属性为其名称。
Test.wizardy只是一个变量,它的名称与该函数的值无关。

与以下内容相同:

>>> def unique(): pass
...
>>> unique
<function unique at 0x0000000002CA4F28>
>>> unique.__name__
'unique'
>>> f = unique
>>> f.__name__
'unique'
>>> class A: pass
...
>>> a = A()
>>> a.g = unique
>>> a.g
<function unique at 0x0000000002CA4F28>
>>> a.g.__name__
'unique'

答案 1 :(得分:0)

您可以通过检查self.__class__.__dict__的内容来实现:

class Test:
    pass

def my_unique_method_name(self):
    for k, v in self.__class__.__dict__.items():
        if v == my_unique_method_name:
            print(k)
            break  # Assume there's only one.


Test.wizardry = my_unique_method_name
t = Test()
t.wizardry()  # -> wizardry

这是一种更通用(因此可重用)的方式,不需要分配给函数执行任何特殊的操作-由于没有for循环,因此它也可能会更快一些:

from functools import wraps

class Test:
    pass

def my_unique_method_name(self):
    pass

def assign_function_to_method(func, cls, name):
    @wraps(func)  # Optional (but recommended).
    def wrapped(*args, **kwargs):
        print(name)
        return func(*args, **kwargs)

    setattr(cls, name, wrapped)


assign_function_to_method(my_unique_method_name, Test, 'wizardry')
t = Test()
t.wizardry()  # -> wizardry

这两种方法都可以在Python 2和3中使用。