Skip to content

Instantly share code, notes, and snippets.

@jl
Last active October 10, 2015 20:19
Show Gist options
  • Save jl/5ddc1d7673485ed2c68f to your computer and use it in GitHub Desktop.
Save jl/5ddc1d7673485ed2c68f to your computer and use it in GitHub Desktop.
Python 3 named parameters

Let's say you want to write a comparator function that takes two objects.

def is_newer(older, newer):
    return older.timestamp < newer.timestamp

def keep_newer(file1, file2):
    if is_newer(file1, file2):
        os.unlink(file1)
    else:
        os.unlink(file2)

The function name is_newer() is ambiguous whether the first or second argument is considered the "newer" one. Reviewers of the function keep_newer() cannot trivially verify that the logic is correct without looking up the internals of is_newer().

In Python 3, you can use keyword-only parameters to force callers to name required parameters.

def is_newer(*, older, newer):
    # Everything after * must be a keyword parameter.
    return older.timestamp < newer.timestamp

def keep_newer(file1, file2):
    if is_newer(older=file1, newer=file2):
        os.unlink(file1)
    else:
        os.unlink(file2)

Now, someone who reads keep_newer() has a pretty good idea of what is going on at the point what is now a self-documenting function call. It's overkill to use this everywhere, but can be useful when extra clarity is needed.

In Python 2, you could get close with keyword arguments:

def is_newer(older=None, newer=None):
    assert older is not None
    assert newer is not None
    return older.timestamp < newer.timestamp

However, it's not quite as clean, and there might not be illegal default values that make sense in every case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment