[Python-ideas] make __closure__ writable

Yury Selivanov yselivanov.ml at gmail.com
Tue Mar 20 15:59:21 CET 2012


On 2012-03-20, at 10:56 AM, Yury Selivanov wrote:

> Because usually you write decorators as functions, not classes.  And
> when you do the former style, you usually do it in the following way:
> 
> def decorator(func):
>    def wrapper(*args, **kwargs):
>        return func(*args, **kwargs)
> 
>    functools.wraps(wrapper, func)
>    return wrapper
> 
> Now, let's use it:
> 
> @decorator
> def some_func(): pass
> 
> OK.  At this point, 'some_func' object has a '__wrapped__' attribute,
> that points to original 'some_func' function.  But whatever you write
> to 'some_func.__wrapped__' won't change anything, as the 'wrapper'
> will continue to call old 'some_func'.  Instead of assigning something
> to __wrapped__, we need to change it in-place, by doing 
> '__wrapped__.__closure__ = new_closure'.


And as I told you in the first example: there is no problem when you have
only one decorator.  You can surely just return a new FunctionType().

But when you have many of them, such as:

@decorator3
@your_magic_decorator_that_modifies_the_closure
@decorator2
@decorator1
def some_func(): pass

The only way to modify the __closure__ it to write to the __wrapped__ 
attribute of 'decorator1' wrapper.

-
Yury



More information about the Python-ideas mailing list