40

我可以通过以下代码访问函数本身内部的 python 函数属性:

def aa():
    print aa.__name__
    print aa.__hash__
    # other simliar

但是,如果上面的aa()函数是编写其他代码的模板,比如说bb(),我必须写:

def bb():
    print bb.__name__
    print bb.__hash__
    # other simliar

是否有类似于self类方法中的参数的“指针”,所以我可以编写这样的代码?

def whatever():
    print self.__name__
    print self.__hash__
    # other simliar

我搜了一下,发现有人说用类来解决这个问题,但是重新定义所有现有函数可能会很麻烦。有什么建议么?

4

4 回答 4

34

函数没有通用的方法来引用自身。考虑改用装饰器。如果您想要的只是打印有关可以使用装饰器轻松完成的功能的信息:

from functools import wraps
def showinfo(f):
    @wraps(f)
    def wrapper(*args, **kwds):
         print(f.__name__, f.__hash__)
         return f(*args, **kwds)
    return wrapper

@showinfo
def aa():
    pass

如果您确实需要引用该函数,则只需将其添加到函数参数中:

def withself(f):
    @wraps(f)
    def wrapper(*args, **kwds):
        return f(f, *args, **kwds)
    return wrapper

@withself
def aa(self):
      print(self.__name__)
      # etc.

编辑以添加备用装饰器

您还可以编写一个更简单(并且可能更快)的装饰器,使包装函数与 Python 的自省一起正常工作:

def bind(f):
    """Decorate function `f` to pass a reference to the function
    as the first argument"""
    return f.__get__(f, type(f))

@bind
def foo(self, x):
    "This is a bound function!"
    print(self, x)


>>> foo(42)
<function foo at 0x02A46030> 42
>>> help(foo)
Help on method foo in module __main__:

foo(self, x) method of builtins.function instance
    This is a bound function!

这利用了 Python 的描述符协议:函数具有__get__用于创建绑定方法的方法。装饰器只是使用现有方法使函数成为自身的绑定方法。它仅适用于独立功能,如果您希望方法能够引用自身,您将不得不做一些更像原始解决方案的事情。

于 2011-02-21T08:37:04.267 回答
16

http://docs.python.org/library/inspect.html看起来很有希望:

import inspect
def foo():
     felf = globals()[inspect.getframeinfo(inspect.currentframe()).function]
     print felf.__name__, felf.__doc__

您还可以使用该sys模块来获取当前函数的名称:

import sys
def bar():
     felf = globals()[sys._getframe().f_code.co_name]
     print felf.__name__, felf.__doc__
于 2011-02-21T08:23:30.447 回答
0

您至少可以在self = bb第一行中说,然后您只需要在更改函数名称时更改该行,而不是所有其他引用。

self我的代码编辑器也以与类相同的方式突出显示变量。

于 2019-08-18T12:49:23.133 回答
-4

如何快速创建自己的“自我”名称,如下所示:

>>> def f():
...     self = f
...     print "My name is ", self.__name__, "and I am", self.__hash__
...
>>> f()
My name is  f and I am <method-wrapper '__hash__' of function object at 0x00B50F30>
>>> x = f
>>> x()
My name is  f and I am <method-wrapper '__hash__' of function object at 0x00B50F30>
>>>
于 2012-08-07T14:24:10.340 回答