Functions decorator safety in python

How this code works? It is from chapter 8 in "Data Science by Scratch" from the gradient. Why do I need to wrap a function inside another fucntion? Is there a more readable way to achieve this execption handling? Here's the explanation for it.

It is possible that certain step sizes will result in invalid inputs for our function. So we’ll need to create a “safe apply” function that returns infinity (which should never be the minimum of anything) for invalid inputs:

The second time we call safe() which returns a new function with the embedded exception handling. We replace what the name "myfunc" refers to, now it refers to the returned function. The original myfunc is not lost, it is called f inside the new one.

A @safe decorator is essentially doing the same thing as myfunc = safe(myfunc)