代码之家  ›  专栏  ›  技术社区  ›  Mandragor

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

  •  0
  • Mandragor  · 技术社区  · 7 年前

    如何打印我给出的方法名?

    #!/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 回复  |  直到 7 年前
        1
  •  0
  •   molbdnilo    7 年前

    函数的名称 “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
  •  0
  •   martineau    7 年前

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