Boilerplate to decorators via context manager

Boilerplate is the same code repeated again and again and again

 

It is annoying and boring and makes your keyboard wear out quicker

 

It needs to be gone

How can we use features of Python to do this?

 

Lets find out

 

Disclaimer - I am not an expert or Dutch

 

There may be another better way

Lets look at a sample

 

process_1.py - does some steps and logs the entry to each step

 

We want it to also write process log entries somewhere (might a be a database or something else)

So we create recorddetail.py to do that

We start

We stop

 We save

Update our script to use it - process_2.py

 

It works ...

 

But we have the same few lines of code in each function - attack of the boilerplate!

I read about context managers in Python

 

Context managers can be used to allocate and release resources,  eg open() for files

 

See open*.py

 

Can also be used to do something on enter and something on exit

So how do I make a context manager?

 

__enter__() and __exit__()  

OR

@contextmanager and yield

 

(you may of seen yield in generators - see generators.py)

process_3.py and recorddetail3.py

 

Note the class RecordDetail hasnt changed, we just added record_detail

 

process_3.py looks much cleaner

But annoying that have with enclosing whole function

I read about decorators ...

 

Functions in Python are objects like everything else

 

Decorators let us wrap functions with other functions so we can do stuff before and after the function - simple ...

You will have probably come across decorators already and used them

 

decorators.py

An example makes it easier to understand - see recorddetail4.py

 

__call__()

this is called instead of the function it decorates

 

Can now do stuff before and after the function

 

process_4.py 

 

looks a lot neater

 

Note that adding decorator doesn't affect the working of the function

 

But ... look at when __init__ is called ...

scope creep ... we want to stop() even if there is an error ...

 

recorddetail5.py

 

catch exceptions when calling the wrapped function and then re-raise once we are done

 

Demo code : https://github.com/atleypnorth/bp2dvcm

 

Questions ?

 

Boilerplate to decorators via context managers

By Patrick Morris

Boilerplate to decorators via context managers

How to use context managers and decorators in Python

  • 322