вставка функции в пространство имен модуля с помощью декоратора

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

def crossover(cross):  
    def ecspy_crossover(random, candidates, args):  
    # ... decorator magic
    globals()['single_'+cross.func_name] = cross

Однако, когда я импортирую модуль, функции single_* не отображаются. Когда я запускаю pdb в этом модуле, эта функция присутствует в пространстве имен... [в этом модуле нет __all__statement...]

Любые идеи?


person Jelle    schedule 22.02.2011    source источник
comment
В пространстве имен не будет никаких функций single_*, пока вы не выполните crossover() один или несколько раз, что не произойдет волшебным образом при импорте модуля. Вы можете добавить к нему некоторые вызовы на уровне модуля вне каких-либо других функций или определений методов, и они будут выполнены, после чего будут созданы single_* имена функций.   -  person martineau    schedule 22.02.2011


Ответы (1)


Почему бы просто не добавить исходную функцию в качестве атрибута обернутой функции? На самом деле это именно то, что functools.wraps делает в Python 3.2, он сохраняет исходную функцию в атрибуте __wrapped__.

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

person Duncan    schedule 22.02.2011
comment
Я согласен, что functools.wrap действительно полезен для деко, но f.__globals__ был тем, что я искал. По деньгам спасибо Дункан! - person Jelle; 22.02.2011