smith jack wrote: > i have heard that function invocation in python is expensive,
It's expensive, but not *that* expensive. Compare: [steve@sylar ~]$ python3.2 -m timeit 'x = "abc".upper()' 1000000 loops, best of 3: 0.31 usec per loop [steve@sylar ~]$ python3.2 -m timeit -s 'def f(): return "abc".upper()' 'f()' 1000000 loops, best of 3: 0.53 usec per loop So the function call is nearly as expensive as this (very simple!) sample code. But in absolute terms, that's not very expensive at all. If we make the code more expensive: [steve@sylar ~]$ python3.2 -m timeit '("abc"*1000)[2:995].upper().lower()' 10000 loops, best of 3: 32.3 usec per loop [steve@sylar ~]$ python3.2 -m timeit -s 'def f(): return ("abc"*1000 [2:995].upper().lower()' 'f()' 10000 loops, best of 3: 33.9 usec per loop the function call overhead becomes trivial. Cases where function call overhead is significant are rare. Not vanishingly rare, but rare enough that you shouldn't worry about them. > 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? About as long as a piece of string. A more serious answer: it should be exactly as long as needed to do the smallest amount of work that makes up one action, and no longer or shorter. If you want to maximise the programmer's efficiency, a single function should be short enough to keep the whole thing in your short-term memory at once. This means it should consist of no more than seven, plus or minus two, chunks of code. A chunk may be a single line, or a few lines that together make up a unit, or if the lines are particularly complex, *less* than a line. http://en.wikipedia.org/wiki/The_Magical_Number_Seven,_Plus_or_Minus_Two http://www.codinghorror.com/blog/2006/08/the-magical-number-seven-plus-or-minus-two.html (Don't be put off by the use of the term "magical" -- there's nothing literally magical about this. It's just a side-effect of the way human cognition works.) Anything longer than 7±2 chunks, and you will find yourself having to scroll backwards and forwards through the function, swapping information into your short-term memory, in order to understand it. Even 7±2 is probably excessive: I find that I'm most comfortable with functions that perform 4±1 chunks of work. An example from one of my classes: def find(self, prefix): """Find the item that matches prefix.""" prefix = prefix.lower() # Chunk #1 menu = self._cleaned_menu # Chunk #2 for i,s in enumerate(menu, 1): # Chunk #3 if s.lower().startswith(prefix): return i return None # Chunk #4 So that's three one-line chunks and one three-line chunk. -- Steven -- http://mail.python.org/mailman/listinfo/python-list