【问题标题】:How to print method name of dynamically assigned function?如何打印动态分配函数的方法名称?
【发布时间】:2019-02-23 17:20:13
【问题描述】:

当我运行以下代码时,只有方法中的打印语句(我动态分配给“Test”类)只返回“my_unique_method_name”。

如何打印我给它的方法名称?(方法中的“wizardry”——参见下面的“预期输出”。)

#!/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

【问题讨论】:

    标签: python python-3.x function dynamic


    【解决方案1】:

    函数的名称​​是 "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'
    

    【讨论】:

      【解决方案2】:

      你可以通过检查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。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-12-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多