LoginSignup
1
0

More than 5 years have passed since last update.

EP 21 Enforce Clarity with Keyword-Only Arguments

Posted at
  • Keyword arguments make the intention of a function call more clear
  • Use Keyword-only arguments to force callers to supply keyword arguments for potentially confusing functions, especially those that accept multiple Boolean
  • Python 3 supports explicit syntax for keyword-only arguments in functions
  • Python 2 can emulate keyword-only arguments for functions by using **kwargs and munually rasising TypeError

Effective Python

Divide one number by another but be another but be very careful about special cases. Sometimes you want to ignore ZeoroDivisionError exceptions and return infinity instead. Other times, you want to ignore OverflowError exceptions and return zero instead.

def safe_division(number, divisor, ignore_overflow, ignore_zero_division):
    try:
        return number / divisor
    except OverflowError:
        if ignore_overflow:
            return 0
        else:
            raise
    except ZeroDivisionError:
        if ignore_zero_division:
            return float('inf')
        else:
            raise

Using this function is strightforward.

safe_division(1, 0, True, False)

The problem is that it's easy to confuse the position of the two Boolean arguments that control the exception-ignoring behavior. This can easily cause bugs that are hard to track down. One way to improve this readability of this code is to use keyword arguments.

def safe_division_b(number, divisor,
        ignore_overflow=False,
        ignore_zero_division=False):
    pass
safe_division_b(1, 10**500, ignore_overflow=True)
safe_division_b(1, 0, ignore_zero_division=True)

However, since these keyword arguments are optional behavior, there's nothing forcing callers of your functions to use keyword arguments for clarity.

safe_division_b(1, 0, True, False)

In Python3, you can demand clartiy by defining your functions with keyword-only arguments. These arguments can only be supplied by keyword, never by position. Here, I redefine the safe_division functions to accept keyword-only arguments. The * symbol in the argument list indicates the end of positional arguments and the beginning of keyword-only arguments.

def safe_division_c(number, divisor, *,
        ignore_overflow=False,
        ignore_zero_division=False):
    pass

safe_division_c(1, 10**500, True, False)
   safe_division_c(1, 10 **500, True, False)
TypeError: safe_division_c() takes 2 positional arguments but 4 were given
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0