saving and restoring the current decimal contextwhich specifies the precision and rounding characteristics for calculationswith decimal localcontext(as ctxafterimport decimal ctx prec decimal decimal(' 'decimal decimal(' 'after this statement runsthe current thread' context manager state is automatically restored to what it was before the statement began to do the same with tryfinallywe would need to save the context before and restore it manually after the nested block the context management protocol although some built-in types come with context managerswe can also write new ones of our own to implement context managersclasses use special methods that fall into the operator overloading category to tap into the with statement the interface expected of objects used in with statements is somewhat complexand most programmers only need to know how to use existing context managers for tool builders who might want to write new application-specific context managersthoughlet' take quick look at what' involved here' how the with statement actually works the expression is evaluatedresulting in an object known as context manager that must have __enter__ and __exit__ methods the context manager' __enter__ method is called the value it returns is assigned to the variable in the as clause if presentor simply discarded otherwise the code in the nested with block is executed if the with block raises an exceptionthe __exit__(typevaluetracebackmethod is called with the exception details these are the same three values returned by sys exc_infodescribed in the python manuals and later in this part of the book if this method returns false valuethe exception is reraisedotherwisethe exception is terminated the exception should normally be reraised so that it is propagated outside the with statement if the with block does not raise an exceptionthe __exit__ method is still calledbut its typevalueand traceback arguments are all passed in as none let' look at quick demo of the protocol in action the followingfile withas pydefines context manager object that traces the entry and exit of the with block in any with statement it is used forclass traceblockdef message(selfarg)print('running argdef __enter__(self) exception coding details