On Fri, 5 May 2006 08:20:02 -0500, Michael Urman <[EMAIL PROTECTED]> wrote: >On 5/5/06, Terry Reedy <[EMAIL PROTECTED]> wrote: >> At present, Python allows this as a choice. > >Not always - take a look from another perspective: > >def make_person(**kwds): > name = kwds.pop('name', None) > age = kwds.pop('age', None) > phone = kwds.pop('phone', None) > location = kwds.pop('location', None) > ... > >This already requires the caller to use keywords, but results in >horrid introspection based documentation. You know it takes some >keywords, but you have no clue what keywords they are. It's as bad as >calling help() on many of the C functions in the python stdlib. > >So what allowing named keyword-only arguments does for us is allows us >to document this case. That is an absolute win.
Here you go: import inspect @decorator def keyword(f): def g(*a, **kw): if a: raise TypeError("Arguments must be passed by keyword") args = [] expectedArgs = inspect.getargspec(f)[0] defaults = inspect.getargspec(f)[-1] for i, a in enumerate(expectedArgs): if a in kw: args.append(kw[a]) elif i >= len(expectedArgs) - len(defaults): args.append(defaults[i - len(expectedArgs)]) else: raise TypeError("Missing argument for " + a) return f(*args) return g @keyword def foo(a, b, c=10, d=20, e=30): return a, b, c, d, e try: foo() except TypeError: pass else: assert False, "Should have raised TypeError" try: foo(1) except TypeError: pass else: assert False, "Should have raised TypeError" try: foo(a=1) except TypeError: pass else: assert False, "Should have raised TypeError" assert foo(a=1, b=2) == (1, 2, 10, 20, 30) assert foo(a=1, b=2, c=3) == (1, 2, 3, 20, 30) assert foo(a=1, b=2, d=4) == (1, 2, 10, 4, 30) assert foo(a=1, b=2, c=3, d=4, e=5) == (1, 2, 3, 4, 5) print 'Success!' _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com