Using a decorator to bring variables into decorated function namespace
<p>Say I have a function that looks like this:</p>

<pre><code>def func(arg1, arg2):
    return arg1 + arg2 + arg3
</code></pre>

<p>And I want to bring in <code>arg3</code> using an argument passed to a decorator. Is this possible and if so how would this be done?</p>

<p>I've tried this which was suggested <a href="http://www.saltycrane.com/blog/2010/03/simple-python-decorator-examples/" rel="nofollow">here</a> to be able to pass arguments to decorators:</p>

<pre><code>from functools import wraps

def addarg(arg):
    def decorate(func):
        arg3 = arg
        @wraps(func)
        def wrapped(*args):
            return func(*args)
        return wrapped
    return decorate

@addarg(3)
def func(arg1, arg2):
    return arg1 + arg2 + arg3

if __name__ == "__main__":
    print(func(1, 2))
</code></pre>

<p>But I get this error (understandably):</p>

<pre><code>Traceback (most recent call last):
  File "C:/Users/pbreach/Dropbox/FIDS/PhD/Code/anemi3/utils.py", line 19, in &lt;module&gt;
    print(func(1, 2))
  File "C:/Users/pbreach/Dropbox/FIDS/PhD/Code/anemi3/utils.py", line 9, in wrapped
    return func(*args)
  File "C:/Users/pbreach/Dropbox/FIDS/PhD/Code/anemi3/utils.py", line 16, in func
    return arg1 + arg2 + arg3
NameError: name 'arg3' is not defined
</code></pre>

<p>For my application it would be much nicer to be able to define the function in this way. There are other ways but then more code will have to be added to the body of each function.</p>

<p>You can do it like that</p>

<pre><code>from functools import wraps

def addarg(arg):
    def decorate(func):
        @wraps(func)
        def wrapped(*args):
            return func(*args, arg)
        return wrapped
    return decorate

@addarg(3)
def func(arg1, arg2, *args):
    return arg1 + arg2 + sum(args)


if __name__ == "__main__":
     print(func(1, 2))
</code></pre>

<p>So that you are not attached to any name and you can apply as many decorators as you want. So if you want to add more decorators it would work. For example</p>

<pre><code>@addarg(3)
@addarg(3)
@addarg(3)
def func(arg1, arg2, *args):
    return arg1 + arg2 + sum(args)

if __name__ == "__main__":
     print(func(1, 2))

# Output would be 12(1 + 2 + 3 + 3 + 3)
</code></pre>

python function namespaces python-decorators