2011-02-10 3 views
1

Предполагая, что у меня есть декоратор и обернутая функция:Путь импорта для обернутой декоратором функции?

def squared(method): 
    def wrapper(x, y): 
     return method(x*x, y*y) 
    return wrapper 

@squared 
def sum(x, y): 
    return x+y 

У меня есть другой код, который хотел бы назвать недекорированную версию функции sum. Есть ли трюк для импорта, который может привлечь меня к этому развернутому методу? Если мой код говорит from some.module.path import sum, тогда я получаю завернутую версию метода sum, чего я не хочу в этом случае. (Да, я знаю, что я мог бы разбить это на вспомогательный метод, но это нарушает некоторую чистоту рисунка, который я собираюсь здесь.)

Я в порядке с добавлением дополнительной «магии» к декоратору для предоставления некоторого альтернативного имени символа (например, orig_sum), который я мог бы затем импортировать, я просто не знаю, как это сделать.

ответ

4
def unwrap(fn): 
    return fn.__wrapped__ 

def squared(method): 
    def wrapper(x, y): 
     return method(x*x, y*y) 
    wrapper.__wrapped__ = method 
    return wrapper 

@squared 
def sum(x, y): 
    return x+y 

sum(2,3)  -> 13 
unwrap(sum)(2,3) -> 5 
+0

Из другого исходного файла, можно ли «из foo.squared.wrapper import orig as sum'? – slacy

+0

@slacy, я должен сказать, что ИМО, что вы предлагаете, гораздо менее «чист», чем версия декоратора Райнера Геркеке. – senderle

+0

Кстати, даже лучше было бы 'setattr (wrapped, method .__ name__, method)' :) – slacy

3

Что относительно этого?

def squared(method): 
    def wrapper(x, y): 
     return method(x*x, y*y) 
    return wrapper 

def sum(x, y): 
    return x+y 

squared_sum = squared(sum) 

Это еще декоратор, но вы все равно можете импортировать squared и sum без всякой магии. Не уверен, что это то, что вы имели в виду под «вспомогательным методом», но я нахожу это намного чище, чем метод sum, который фактически суммирует квадраты его входов.

+0

Да, это, конечно, будет работать, но в нем нет чистоты синтаксиса декоратора Python. :) Как вы, вероятно, догадались, я на самом деле не суммирую и не возлагаю на квадрат в моем коде, это просто синтетический пример, который иллюстрирует поведение, которое я хочу. Но ваша точка верна, и, возможно, я не должен использовать синтаксис @decorator. – slacy

+0

опоздать на вечеринку, но вы могли бы: @squared def squared_sum (x, y): return sum (x, y) – Willyfrog

Смежные вопросы