coursewe could sort by forename and then surname by changing the order of the attribute names we give to the sortkey functor another way of achieving the same thingbut without needing to create functor at allis to use the operator module' operator attrgetter(function for exampleto sort by surname we could writepeople sort(key=operator attrgetter("surname")and similarlyto sort by surname and forenamepeople sort(key=operator attrgetter("surname""forename")the operator attrgetter(function returns function ( closurethatwhen called on an objectreturns those attributes of the object that were specified when the closure was created functors are probably used rather less frequently in python than in other languages that support them because python has other means of doing the same things--for exampleusing closures or item and attribute getters context managers |context managers allow us to simplify code by ensuring that certain operations are performed before and after particular block of code is executed the behavior is achieved because context managers define two special methods__enter__(and __exit__()that python treats specially in the scope of with statement when context manager is created in with statement its __enter__(method is automatically calledand when the context manager goes out of scope after its with statement its __exit__(method is automatically called we can create our own custom context managers or use predefined ones--as we will see later in this subsectionthe file objects returned by the built-in open(function are context managers the syntax for using context managers is thiswith expression as variablesuite the expression must be or must produce context manager objectif the optional as variable part is specifiedthe variable is set to refer to the object returned by the context manager' __enter__(method (and this is often the context manager itselfbecause context manager is guaranteed to execute its "exitcode (even in the face of exceptions)context managers can be used to eliminate the need for finally blocks in many situations some of python' types are context managers--for exampleall the file objects that open(can return--so we can eliminate finally blocks when doing file handling as these equivalent code snippets illustrate (assuming that process(is function defined elsewhere)