[Python-ideas] About the passing the function arguments in Keyword form.
Eric V. Smith
eric at trueblade.com
Mon Dec 24 11:30:59 EST 2018
On 12/24/2018 5:21 AM, 李默 wrote:
> I am having an idea on loosing the argument validity check when passing
> the function arguments in keyword way.
> For example:
> -------------------------------
> deff(x, y):
>
> print(x, y) def call_f(): f(x=7, y=9, z=9)
>
> call_f()
>
> ------------------------------
>
> In the current of python, the extra pass of 'z' would let the
> interpreter raise an exception and stop work. My idea is that the
> interpreter need not stop because all the needed args are completely
> provided. Of course for this toy example, 'f' can be define as f(x, y,
> **kwargs) to achieve the same goal. However, essentially it is
> reasonably to keep interpreter going as long as enough args are passed.
> And this modification can bring more freedom of programming.
>
>
> Think about the following situations:
>
> situation 1) there are many 'f's written by other people, and their args
> are very similar and your job is to run each of them to get some results.
>
> ---------------------
>
> ##########code by others:
>
> def f0(): ... def f1(x): ... def f2(x, y): ... def f3(x, y, z): ...
>
> #if passing extra args are valid, you can run all the functions in the
> following way, which is very compact and easy to read.
>
> def test_universal_call():
>
> funcs = [f0, f1, f2, f3] args = {'x':1, 'y':5, 'z':8} for f in funcs:
> f(**args)
>
> ------------------
>
>
> situation 2) there are several steps for make one product, each step is
> in an individual function and needs different args.
>
> ------------------
>
> def make_oil(oil): ...
>
> def make_water( water): ...
>
> def make_powder(powder): ...
>
> ## if passing extra args are valid, you can run all the functions in the
> following way, which is very compact and easy to read.
>
> def dish(): procedures = [make_oil, make_water, make_powder]
>
> args = {'oil' : 1, 'water': 10, 'powder': 4} for f in procedures: f(**args)
>
>
> ---------------
>
>
> This idea is different from **kwargs. **kwargs are used when user wants
> to record all the keywords passed. This idea is that even if the user
> doesn’t want to record the arguments, that extra pass of keyword
> arguments wont’t cause an exception.
I agree with other posters that we definitely do not want this as the
default behavior in Python. However, it's also sometimes a useful
pattern. I use it when I have a large plugin architecture that can take
dozens or hundreds of possible parameters, but any given plugin is
likely to only use a few parameters. I've written calllib
(https://pypi.org/project/calllib/) to support this. It might achieve
your goals.
This code:
-------------------
from calllib import apply
def f0():
print('f0')
def f1(x):
print(f'f1 {x!r}')
def f2(x, y):
print(f'f2 {x!r} {y!r}')
def f3(x, y, z):
print(f'f3 {x!r} {y!r} {z!r}')
def test_universal_call():
funcs = [f0, f1, f2, f3]
args = {'x':1, 'y':5, 'z':8}
for f in funcs:
apply(f, args)
test_universal_call()
-------------------
produces:
f0
f1 1
f2 1 5
f3 1 5 8
Eric
More information about the Python-ideas
mailing list