::  Posts  ::  RSS  ::  ◂◂RSS  ::  Contact

Require Keyword Arguments

July 13th, 2014
python, tech

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)
      return checked_f

    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:
    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

More Posts:

Older Post:

Newer Post:

  ::  Posts  ::  RSS  ::  ◂◂RSS  ::  Contact