[Python-ideas] Extending the usage of the @ decoration operator.
Chris B
accountearnstar at gmail.com
Sat May 17 03:40:25 CEST 2014
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.").
@dec1(arg)
@dec2
def func(): pass
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:
@dec1(arg)
@dec2
def func(): pass
is equivalent to:
def func(): pass
func = dec1(arg)(dec2(func))
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:
def foo(): pass
foo @ decorator
def bar(): pass
is equivalent to:
def foo(): pass
foo = decorator(func)
def bar(): pass
This doesn't allow us to have stacked decorators so, the use of a tuple is
needed:
def func(): pass
func @ (dec2, dec1(arg))
is equivalent to:
def func(): pass
func = dec1(arg)(dec2(func))
Why not decorate more than one function at once?:
func1, func2, func3 @ dec1(arg), dec2
is equivalent to:
func1 = dec1(arg)(dec2(func1))
func2 = dec1(arg)(dec2(func2))
func3 = dec1(arg)(dec2(func3))
or better:
_temp1 = dec1(arg)(dec2(func1))
_temp2 = dec1(arg)(dec2(func2))
_temp3 = dec1(arg)(dec2(func3))
func1, func2, func3 = _temp1, _temp2, _temp3
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:
from os.path import expandvars, abspath, normcase
p1 = input('Insert path here: )
p2 = input('And another path here: )
# Fix the path strings
p1, p2 @ expandvars, abspath, normcase
Functions that take more than one argument can't be used as modifiers. But
simply currying them solves the problem:
from os.path import expandvars, abspath, normcase, relpath
def curry(f, *args, **kwargs):
def curried_f(arg1):
return f(arg1, *args, **kwargs)
return curried_f
# Fix the path strings
p1, p2 @ expandvars, abspath, normcase, curry(relpath, start)
Storing the modifiers in a mutable like a list, one could do rather complex
stuff:
def add(a, b):
return a + b
def sub(...; def mult(...; def div(... # ...the obvious way.
def permutations(L):
for _ in range(possible_permutations)
next_permutation = ...
yield next_permutation
L = [curry(add, 1), curry(sub, 2), curry(mult, 3), curry(div, 4)]
# Prints the result for all possible combinations of the four operations
+1, -2, *3, /4
# applied to 1.
for permutation in permutations(L):
x = 1
x @ permutation
print(x)
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!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20140517/534a793c/attachment.html>
More information about the Python-ideas
mailing list