""" Uses the same logcall function as decorators1.py does, but uses it as a decorator of a user-defined function instead of calling it directly """ def logcall(f): """A function-wrapping function: logcall(f) returns a function just like f except it prints its arguments and return values""" def logcall_wrapper(*args, **kargs): print(f.__name__,'arguments',args, kargs,) retval = f(*args, **kargs) print(f.__name__,'returns',retval) return retval # rename the wrapper; only matters for a few debugging tools logcall_wrapper.__name__ = 'logcall('+f.__name__+')' return logcall_wrapper # @func before a function name means "after defining the function, replace it with func(itself)" # i.e., this example is the same as # # def compare(a,b): # ... # code here # compare = logcall(compare) # # the @func line is called a "decorator" @logcall def compare(a,b): try: if a < b: return 'less' elif a == b: return 'same' else: return 'more' except TypeError as ex: return 'incomparable', str(ex) print([compare(a,b) for a,b in zip(range(-2,3), range(-3,7,2))]) print(compare(b=3,a=None)) print(compare(1, b=-1)) print(compare.__name__)