for our first decorator examplelet us suppose that we have many functions that perform calculationsand that some of these must always produce positive result we could add an assertion to each of thesebut using decorator is easier and clearer here' function decorated with the @positive_result decorator that we will create in moment@positive_result def discriminant(abc)return ( * ( cthanks to the decoratorif the result is ever less than an assertionerror exception will be raised and the program will terminate and of coursewe can use the decorator on as many functions as we like here' the decorator' implementationdef positive_result(function)def wrapper(*args**kwargs)result function(*args**kwargsassert result > function __name__ "(result isn' > return result wrapper __name__ function __name__ wrapper __doc__ function __doc__ return wrapper decorators define new local function that calls the original function herethe local function is wrapper()it calls the original function and stores the resultand it uses an assertion to guarantee that the result is positive (or that the program will terminatethe wrapper finishes by returning the result computed by the wrapped function after creating the wrapperwe set its name and docstring to those of the original function this helps with introspectionsince we want error messages to mention the name of the original functionnot the wrapper finallywe return the wrapper function--it is this function that will be used in place of the original def positive_result(function)@functools wraps(functiondef wrapper(*args**kwargs)result function(*args**kwargsassert result > function __name__ "(result isn' > return result return wrapper here is slightly cleaner version of the @positive_result decorator the wrapper itself is wrapped using the functools module' @functools wraps decoratorwhich ensures that the wrapper(function has the name and docstring of the original function