I have no Python 3.8 installed now, maybe walrus operator (:=) allows this?! Not sure. However, you can build your own solution, using inspect module e.g. something like this:
import inspect
from functools import wraps
class Placeholder:
__slots__ = ('expr', )
def __init__(self, expr):
self.expr=expr
def use_var_expr(expr):
return Placeholder(expr)
def allow_inline_assignment(f):
@wraps(f)
def wrapper(*args, **kwargs):
env = {k: v.default for k, v in inspect.signature(f).parameters.items() if not isinstance(v.default, Placeholder)}
new_kwargs = dict()
for k, v in inspect.signature(f).parameters.items():
if v.default is not inspect._empty:
if isinstance(v.default, Placeholder):
exec('result = ' + v.default.expr, env)
new_kwargs.update({k: env.get('result')})
else:
new_kwargs.update({k: v.default})
return f(*args, **new_kwargs)
return wrapper
@allow_inline_assignment
def a(z, x=4, p=use_var_expr('x * x**2')):
print("Positional arg: ", z)
print("First keyword value: ", x)
print("Second keyword value: ", p)
a(3)
Output:
Positional arg: 3
First keyword value: 4
Second keyword value: 64
Note: this solution is just for fun; it uses exec and, therefore, maybe unsafe.