Coding style

Peter Otten __peter__ at web.de
Tue Jul 18 03:28:46 EDT 2006


Carl Banks wrote:

> 
> Peter Otten wrote:
>> Carl Banks wrote:
>>
>> >     def process_values(lst):
>> >         if not lst:
>> >             return
>> >         do_expensive_initialization_step()
>> >         for item in lst:
>> >             do_something_with(item)
>> >         do_expensive_finalization_step()
>>
>> > What if you called the function like this:
>> >
>> >     process_values(x.strip() for x in values_lst)
>> >
>> > Oops, now we've just gone through an expensive initialization and
>> > finalization for nothing (since values_lst was empty).  Maybe some
>> > subtle bugs introduced.  If we're lucky, the finalization step will
>> > throw an exception.
>>
>> The good news is that the above has a 99 percent chance that it just
>> works with iterators/generators -- even though the writer may not have
>> been aware of them/they didn't exist when the code was written...
> 
> There's a litmus test I like to use when justifying something with
> percentages: I imagine that I'm presenting it to my boss, and ask
> myself if I still expect to have a job the next day. :-)

That 99 percent chance is not meant to exempt you from actually verifying
that it works. Docstrings can do wonders here

def process_values(lst):
   "Foos all bars in a list"

vs

def process_values(lst):
   "Foos all bars in an iterable"
 
If in doubt, pass a list (-comprehension) as there are other ways of quiet
failure (the function may loop twice over its argument).

> Yes, I agree with you, it most cases I expect merely unnecessary work.
> (Which is not the best news; the best news would be an exception right
> away.)  That's why I think this is only a "pretty good" reason to use
> "if len(lst)>0", not a slam dunk.

If process_values() were /aware/ of iterators it would probably be written

def process_values(items):
    first_pass = True
    for item in items:
        if first_pass:
           do_expensive_initialization_step()
           first_pass = False 
        do_something_with(item)
    if not first_pass:
        do_expensive_finalization_step()

or just with an additional

items = list(items)

as its first statement.

Peter





More information about the Python-list mailing list