is there any principle when writing python function

Roy Smith roy at panix.com
Fri Aug 26 07:15:52 EDT 2011


In article 
<c2fe3168-92b1-46a1-a176-0914f0ba9579 at 19g2000vbv.googlegroups.com>,
 ting at thsu.org wrote:

> On Aug 23, 7:59 am, smith jack <thinke... at gmail.com> wrote:
> > i have heard that function invocation in python is expensive, but make
> > lots of functions are a good design habit in many other languages, so
> > is there any principle when writing python function?
> > for example, how many lines should form a function?
> 
> My suggestion is to think how you would test the function, in order to
> get 100% code coverage.

I'm not convinced 100% code coverage is an achievable goal for any major 
project.  I was once involved in a serious code coverage program.  We 
had a large body of code (100's of KLOC of C++) which we were licensing 
to somebody else.  The customer was insisting that we do code coverage 
testing and set a standard of something like 80% coverage.

There was a dedicated team of about 4 people working on this for the 
better part of a year.  They never came close to 80%.  More like 60%, 
and that was after radical surgery to eliminate dead code and branches 
that couldn't be reached.  The hard parts are testing the code that 
deals with unusual error conditions caused by interfaces to the external 
world.

The problem is, it's just damn hard to simulate all the different kinds 
of errors that can occur.  This was network intensive code.  Every call 
that touches the network can fail in all sorts of ways that are near 
impossible to simulate.  We also had lots of code that tried to deal 
with memory exhaustion.  Again, that's hard to simulate.

I'm not saying code coverage testing is a bad thing.  Many of the issues 
I mention above could have been solved with additional abstraction 
layers, but that adds complexity of its own.  Certainly, designing a 
body of code to be testable from the get-go is a far superior to trying 
to retrofit tests to an existing code base (which is what we were doing).

> The parts of the function that are difficult
> to test, those are the parts that you want to pull out into their own
> separate function.
> 
> For example, a block of code within a conditional statement, where the
> test condition cannot be passed in, is a prime example of a block of
> code that should be pulled out into a separate function.

Maybe.  In general, it's certainly true that a bunch of smallish 
functions, each of which performs exactly one job, is easier to work 
with than a huge ball of spaghetti code.  On the other hand, interfaces 
are a common cause of bugs.  When you pull a hunk of code out into its 
own function, you create a new interface.  Sometimes that adds 
complexity (and bugs) of its own.

> Obviously, there are times where this is not practical - exception
> handling comes to mind - but that should be your rule of thumb. If a
> block of code is hard to test, pull it out into it's own function, so
> that it's easier to test.

In general, that's good advice.  You'll also usually find that code 
which is easy to test is also easy to understand and easy to modify.



More information about the Python-list mailing list