Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Isn't this doing the thing you want?</p> <pre><code>import functools from itertools import product def the_list(): return ["foo", "bar", "baz"] def do_all(func): if hasattr(func, 'get_from'): @functools.wraps(func) def wrapper(*args, **kwargs): return tuple(func(*args) for args in product(*(lf() for lf in func.get_from))) return wrapper return func def gets_arg_from(*list_funcs): def decorator(func): func.get_from = list_funcs return func return decorator @gets_arg_from(the_list) def print_func(word): return word print print_func('foo') all = do_all(print_func) print all() </code></pre> <p><em><strong>Edit:</strong> Explanation</em></p> <p>These two code segments are identical:</p> <pre><code>@deco def func(...): some code </code></pre> <p>is the same as</p> <pre><code>func = deco(lambda ...: some code) </code></pre> <p>@something is just a syntactic sugar for the function call and anonymous function creation...</p> <p>I'll explain what happened in the next peace of code step by step:</p> <pre><code>@gets_arg_from(the_list) def print_func(word): return word </code></pre> <ol> <li><p>First Python creates an anonimous function that receives a parameter <code>word</code> and has a body that just returns this <code>word</code> (or does whatever the function body does)</p></li> <li><p>Then the function <code>get_arg_from</code> gets called and <code>the_list</code> gets passed to it as an argument</p></li> <li><p><code>get_arg_from</code> creates a <code>decorator</code> function and returnes it</p></li> <li><p>The <code>decorator</code> function returned from the <code>get_arg_from</code> is called (this is the syntactic sugar thing) passing as an argument <code>func</code> the anonimous function created in the step 1.</p></li> <li><p><code>decorator</code> just assigns the <code>list_funcs</code> tuple to the <code>get_from</code> attribute of the anonymous function and returns the anonimous function</p></li> <li><p>The return value of the <code>decorator</code> function is assigned to a variable <code>print_func</code></p></li> </ol> <p>Similar effect can be achieved with:</p> <pre><code>def __anonimous(word): return word __decorator = gets_arg_from(the_list) print_func = __decorator(__anonimous) </code></pre> <p>So basically <code>gets_arg_from</code> is not a decorator it's a function that returns a decorator.</p> <p><code>do_all</code> on the other hand <strong>is</strong> a decorator, it receives a function as an argument, and returns either the original function (if the function doesn't have the attribute <code>get_from</code>) or a <code>wrapper</code> function which replaces the original function (if it has the <code>get_from</code> attribute).</p> <p>You can find more examples <a href="http://en.wikipedia.org/wiki/Python_syntax_and_semantics#Decorators" rel="nofollow">here</a>.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload