<div dir="ltr"><div><div><div><div><div><div><div><div><div><div><div><div><div><div>Right now, one can use the @ symbol only for decorations and only bofore function or class definition. ("A decorator is just a callable that takes a function as an argument and returns a replacement
function.").<br><br></div><div>@dec1(arg)<br></div><div>@dec2<br></div><div>def func(): pass</div><br><div><br></div>If a function has already been defined, it cannot be decorated using the decoration operator. But it can still be decorated by explicitly calling the decorator:<br>
<br><div>@dec1(arg)<br></div><div>@dec2<br></div><div>def func(): pass</div><br></div><div>is equivalent to:<br></div><div><br></div><div>def func(): pass<br></div><div>func = dec1(arg)(dec2(func))<br></div><br><br></div>
Now I propose that the @ symbol should also be usable as an assignment operator, in which case a succeeding function definition would not be decorated:<br><br></div><div>def foo(): pass<br>foo @ decorator<br></div><div>def bar(): pass<br>
</div><div><div style class=""><div class=""><div style class="">
</div>
<p>is equivalent to:</p>
<div style class=""><div class=""><div>def foo(): pass<br></div>foo = decorator(func)<br>def bar(): pass<br></div>
</div></div></div><br></div>This doesn't allow us to have stacked decorators so, the use of a tuple is needed:<br><br><div>def func(): pass<br></div>func @ (dec2, dec1(arg))<br><div style class="">
</div>
<p>is equivalent to:</p><div>def func(): pass<br></div>func = dec1(arg)(dec2(func))<br><br></div>Why not decorate more than one function at once?:<br><br></div>func1, func2, func3 @ dec1(arg), dec2<br><br></div>is equivalent to:<br>
<br>func1 = dec1(arg)(dec2(func1))<br>func2 = dec1(arg)(dec2(func2))<br>func3 = dec1(arg)(dec2(func3))<br><br></div><div>or better:<br></div><div><br></div>_temp1 = dec1(arg)(dec2(func1))<br>_temp2 = dec1(arg)(dec2(func2))<br>
_temp3 = dec1(arg)(dec2(func3))<br></div><div>func1, func2, func3 = _temp1, _temp2, _temp3</div><div><br></div>The @ operator would still be only used for function decoration. But it should pass any object preceding it as the (only) argument to the first callable - let's call them modifiers - in the tuple succeeding it and then pass the return value to the next modifier in the tuple. The last return value should then be assigned to the variable again. Consider the following example:<br>
<br></div><div>from os.path import expandvars, abspath, normcase<br></div><div><br></div>p1 = input('Insert path here: )<br>p2 = input('And another path here: )<br><br></div># Fix the path strings<br></div>p1, p2 @ expandvars, abspath, normcase<br>
<br><br></div>Functions that take more than one argument can't be used as modifiers. But simply currying them solves the problem:<br><br>from os.path import expandvars, abspath, normcase, relpath<br><br></div>def curry(f, *args, **kwargs):<br>
<div><div><div><div><div>    def curried_f(arg1):<br></div><div>        return f(arg1, *args, **kwargs)<br></div><div>    return curried_f<br><br># Fix the path strings<br>p1, p2 @ expandvars, abspath, normcase, curry(relpath, start)<br>
<br><br></div><div>Storing the modifiers in a mutable like a list, one could do rather complex stuff:<br><br></div><div>def add(a, b):<br></div><div>    return a + b<br></div><div>def sub(...; def mult(...; def div(... # ...the obvious way.<br>
<br></div><div>def permutations(L):<br></div><div>    for _ in range(possible_permutations)<br></div><div>        next_permutation = ...<br></div><div>            yield next_permutation<br><br></div><div>L = [curry(add, 1), curry(sub, 2), curry(mult, 3), curry(div, 4)]<br>
<br># Prints the result for all possible combinations of the four operations +1, -2, *3, /4<br></div><div># applied to 1.<br></div><div>for permutation in permutations(L):<br></div><div>    x = 1<br></div><div>    x @ permutation<br>
</div><div>    print(x)<br><br><br></div><div>I'm not sure where to go from here. Does this idea qualify for a PEP? Is it even possible to be implemented? Has it already been discussed? What do you think about it? Please share your opinions, suggestions and improvements!<br>
</div></div></div></div></div></div>