Подтвердить что ты не робот

Существует ли общий способ для функции ссылаться?

Я могу получить доступ к атрибуту функции 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

Я искал и нашел, что кто-то сказал использовать класс для решения этой проблемы, но это может быть проблемой для переопределения всех существующих функций. Любые предложения?

4b9b3361

Ответ 1

Нет никакого общего способа для функции ссылаться на себя. Вместо этого рассмотрите использование декоратора. Если все, что вам нужно, как вы указали, - это распечатать информацию о функции, которую можно легко сделать с помощью декоратора:

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__, который используется для создания связанных методов. Декоратор просто использует существующий метод, чтобы сделать функцию связанным методом. Он будет работать только для автономных функций, если вы хотите, чтобы метод мог ссылаться на себя, вам нужно будет сделать что-то большее, чем оригинальное решение.

Ответ 2

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__

Ответ 3

Вы можете, по крайней мере, сказать self = bb в первой строке, а затем вам нужно изменить эту строку только при изменении имени функции вместо любой другой ссылки.

Мой редактор кода выделяет переменную self так же, как и для классов.

Ответ 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>
>>>