yohhoyの日記

技術的メモをしていきたい日記

キーワード引数の強制

Pythonの関数定義において、キーワード引数形式でのみ実引数を渡せる(keyword-only arguments)よう強制する方法。

# Python 3.x
def f(a, b, *, x=None, y=None):
  print("a={} b={} x={} y={}".format(a, b, x, y))

f(1, 2)       # OK: a=1 b=2 x=None y=None
f(1, 2, x=3)  # OK: a=1 b=2 x=3 y=None
f(1, 2, y=4)  # OK: a=1 b=2 x=None y=4

f(1, 2, 3, 4)  # NG
# TypeError: f() takes 2 positional arguments but 4 were given

この記法はPython 3で導入されたため、Python 2では * 部分でSyntaxErrorとなる。キーワード引数の辞書(**kwargs)を受けるか、特殊なマーカーオブジェクトを利用してエミュレーションする。2020-01-01をもって Python2はEOL

# kwargsを利用
def f(a, b, **kwargs):
  x = kwargs.pop('x', None)
  y = kwargs.pop('y', None)
  print("a={} b={} x={} y={}".format(a, b, x, y))


# 特殊マーカーオブジェクト利用
_end_of_args = object()

def f(a, b, marker=_end_of_args, x=None, y=None):
  if marker != _end_of_args:
    raise TypeError
  print("a={} b={} x={} y={}".format(a, b, x, y))

関連URL: