函数有通用方式自我引用吗?
我可以通过下面的代码在一个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 个回答
0
你可以在第一行写 self = bb
,这样当你改函数名字的时候,只需要改这一行,而不是每个地方都改。
我的代码编辑器会把变量 self
和类的高亮显示方式一样对待。
20
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__
37
没有一种通用的方法让一个函数能自我引用。可以考虑使用装饰器来解决这个问题。如果你只是想打印一些关于这个函数的信息,使用装饰器就能很简单地做到:
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__
方法,用于创建绑定方法。这个装饰器简单地使用现有的方法,让函数成为它自己的绑定方法。它只适用于独立的函数,如果你想让一个方法能够引用自己,就需要做一些更复杂的事情,类似于最初的解决方案。