vks vks - 9 months ago 45
Python Question

Decorators not changing dir()

Python decorators when used without


changes the original function's
which is understandable as decorator is simply


but why doesnt it change dir(fun) for that function ? shouldn't it change as well ?

For example:

def wow(func):
def __wow():
return func()
return __wow

def fun():
print "yes"
print fun.__name__
print dir(fun)

The output is

__wow => name of decorator
[... '__sizeof__', '__str__', '__subclasshook__', 'b', 'func_closure', ...]

If you see here,when we print
it is of
but when we print
its of
is in there.So why is
there?Shouldnt it be
as fun.name gives that of decorator

Answer Source

You seem to miss a crucial step in decorators. You do grasp that using a decorator @decorate on a function fun does this:

fun = decorate(fun)

but then don't follow through. fun is now bound to the return value of the decorator.

You said:

Python decorators [...] changes the original function's __doc__, __name__, help

This is not true. The original, undecorated function is unchanged. It still has the same __doc__, the same __name__, etc. The returned object from the decorator, now bound to the original name, however, may well have a different name or docstring. It is, after all, a different object.

In your sample, you returned __wow from the decorator, so Python assigned that object to fun. fun is just a name here, one that references the result of the decorator. The original fun function is no longer available via that name; at no point are you inspecting the original, undecorated function here.

So using dir() on the name fun means it is applied to whatever fun is bound to now, and that is the __wow function produced by the decorator. Setting attributes on fun, sets attributes on that same function object. All attributes reflect this.

You may find it helpful to step through what Python does and visualise those steps. See this Python Tutor visualisation; it shows you what fun references in the end (and where the original function object ended up):

references in the Python Tutor visualisation