is there any principle when writing python function
roy at panix.com
Fri Aug 26 13:15:52 CEST 2011
<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
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