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
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/