For my own entertainment, I was wondering how to achieve the following:
functionA = make_fun([\'paramA\', \'paramB\'])
functionB = make_fun([\'arg1\', \'arg2\',
One of the possible solutions using a class:
def make_fun(args_list):
args_list = args_list[:]
class MyFunc(object):
def __call__(self, *args, **kwargs):
if len(args) > len(args_list):
raise ValueError('Too many arguments passed.')
# At this point all positional arguments are fine.
for arg in args_list[len(args):]:
if arg not in kwargs:
raise ValueError('Missing value for argument {}.'.format(arg))
# At this point, all arguments have been passed either as
# positional or keyword.
if len(args_list) - len(args) != len(kwargs):
raise ValueError('Too many arguments passed.')
for arg in args:
print(arg)
for arg in args_list[len(args):]:
print(kwargs[arg])
return MyFunc()
functionA = make_fun(['paramA', 'paramB'])
functionB = make_fun(['arg1', 'arg2', 'arg3'])
functionA(3, paramB=1) # Works
try:
functionA(3, 2, 1) # Fails
except ValueError as e:
print(e)
try:
functionB(0) # Fails
except ValueError as e:
print(e)
try:
functionB(arg1=1, arg2=2, arg3=3, paramC=1) # Fails
except ValueError as e:
print(e)