Tobiah wrote: > >> Furthermore: If you are moving code out of one function to ONLY be >> called by that ONE function then you are a bad programmer and should >> have your editor taken away for six months. You should ONLY create >> more func/methods if those func/methods will be called from two or >> more places in the code. The very essence of func/meths is the fact >> that they are reusable. > > While I understand and agree with that basic tenet, I think > that the capitalized 'ONLY' is too strong. I do split out > code into function for readability, even when the function > will only be called from the place from which I split it out.
In other words, you disagree. Which is good, because the text you quote is terrible advice, and it is ironic that the person you quote judges others as bad programmers when his advice is so bad. I can think of at least five reasons apart from re-use why it might be appropriate to pull out code into its own function or method even if it is used in one place only: (1) Extensibility. Just earlier today I turned one method into three: def select(self): response = input(self) if response: index = self.find(response) else: index = self.default return self.menuitems[index-1] turned into: def choose(self, response): if response: index = self.find(response) else: index = self.default return self.menuitems[index-1] def raw_select(self): return input(self) def select(self): return self.choose(self.raw_select()) I did this so that subclasses could override the behaviour of each component individually, even though the caller is not expected to call raw_select or choose directly. (I may even consider making them private.) (2) Testing. It is very difficult to reach into the middle of a function and test part of it. It is very difficult to get full test coverage of big monolithic blocks of code: to ensure you test each path through a big function, the number of test cases rises exponentially. By splitting it into functions, you can test each part in isolation, which requires much less work. (3) Fault isolation. If you have a 100 line function that fails on line 73, that failure may have been introduced way back in line 16. By splitting the function up into smaller functions, you can more easily isolate where the failure comes from, by checking for violated pre- and post-conditions. (4) Maintainability. It's just easier to document and reason about a function that does one thing, than one that tries to do everything. Which would you rather work with, individual functions for: buy_ingredients clean_kitchen_work_area wash_vegetables prepare_ingredients cook_main_course fold_serviettes make_desert serve_meal do_washing_up etc., or one massive function: prepare_and_serve_five_course_meal Even if each function is only called once, maintenance is simpler if the code is broken up into more easily understood pieces. (5) Machine efficiency. This can go either way. Code takes up memory too, and it may be easier for the compiler to work with 1000 small functions than 1 big function. I've actually seen somebody write a single function so big that Python couldn't import the module, because it ran out of memory trying to compile it! (This function was *huge* -- the source code was many megabytes in size.) I don't remember the details, but refactoring the source code into smaller functions fixed it. On the other hand, if you are tight for memory, 1 big function may have less overhead than 1000 small functions; and these days, with even entry level PCs often having a GB or more of memory, it is rare to come across a function so big that the size of code matters. Even a 10,000 line function is likely to be only a couple of hundred KB in size: >>> text = '\n'.join('print x+i' for i in range(1, 10001)) >>> code = compile(text, '', 'exec') >>> sys.getsizeof(code.co_code) # size in bytes 90028 So that's four really good reasons for splitting code into functions, and one borderline one, other than code re-use. There may be others. -- Steven -- http://mail.python.org/mailman/listinfo/python-list