В Python, как я могу получить имя функции, передаваемой моему декоратору с параметрами? - PullRequest
1 голос
/ 10 июля 2019

Я пытаюсь создать декоратор, который проверит наличие параметра и получит имя метода, который оформлен.

Мне удалось получить доступ к названию метода в моем втором слое функции, но не в первом.

Например, у меня есть этот декоратор

def p_decorate(name, *a, **k):
    print(name + ' is at object: ')
    print a #I would like to get the method object here
    def fn(*a, **k)
        print a #object prints here instead
    return fn
return p_decorate

У меня есть этот класс, который я хотел бы украсить

class Person(object):
    @p_decorate('John')
    def get_fullnameobject(self):
        return self.name

Я ожидаю, что он напечатает:

John is at object: (<function get_fullnameobject at 0x000000003745A588>,)
(<function get_fullnameobject at 0x000000003745A588>,)

но вывод:

John is at object: ()
(<function get_fullnameobject at 0x000000003745A588>,)

Ответы [ 2 ]

1 голос
/ 10 июля 2019

Вам нужна другая вложенная функция для определения декоратора, который принимает аргументы.

def p_decorate(name):
    def _(f):
        print(name + ' is at object: ')
        print f
        def fn(*a, **k):
            # Do something, but ultimately you probably want to call f
            ...
        return fn
    return _

p_decorate("John") возвращает фактический декоратор, который принимает get_fullnameobject в качестве аргумента f и возвращает новый объект fn для привязки к get_fullnameobject. Без синтаксиса декоратора использование выглядит как

def get_fullnameobject(self):
    return self.name

get_fullnameobject = p_decorate("John")(get_fullnameobject)
1 голос
/ 10 июля 2019

Функция p_decorate называется с единственным аргументом John (*a и **k оба будут пустыми), поэтому вы получаете пустой кортеж для a.

Просто чтобы заметить, возвращаемый вызываемый fn вызывается с последующим вызовом get_fullnameobject.

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

...