Require Keyword Arguments
To avoid errors in calling a python function you might want to ensure it's only ever called with keyword arguments. Say you have:
def score(actual, predicted):
...
and you're worried people accidentally call it with the arguments reversed. After all, nothing looks surprising with:
score(model.predict(data), isRepaid)
We can have a culture where everyone writes in the keyword arguments, as:
score(actual=isRepaid, predicted=model.predict(data))
This mostly solves the problem, but could we have Python check this for us? Yes! PEP 3102 added this to Python 3+:
def score(*, actual, predicted):
..
But what about the Python 2 series? You could rebuild Python with this patch applied, or you could use a decorator that verifies there are no positional arguments and then calls the original function:
def poscheck(f):
def checked_f(*args, **kwargs):
if args:
raise PositionalArgumentsError(f)
f(**kwargs)
return checked_f
@poscheck
def score(actual, predicted):
...
This is pretty good, but what about a case like this:
# Split s on newlines ('\n'), returning a list. These newlines
# are not normally retained, but if the optional keepends argument
# is True then they're kept.
def splitlines(s, keepends=False):
...
If someone calls splitlines
as splitlines(s, True)
that's going to be pretty confusing to a reader. You'd like to make sure writers always make it clear what the boolean is about, so you have a house style where you write splitlines(s, keepends=True)
. If you used poscheck
, though, that would require splitlines(s=s, keepends=True)
which is too verbose. So, use poscheck_except
instead:
@poscheck_except(1)
def splitlines(s, keepends=False):
...
This will require that after the first positional argument all other arguments are given with keywords, if present.
The code is poscheck
on github.
Comment via: google plus, facebook