On Nov 18, 3:02 pm, Steven D'Aprano <ste...@remove.this.cybersource.com.au> wrote: > > That depends on the code. In particular, it depends on how coupled the > code is. Ideally, you should have loosely coupled code, not highly > coupled. If the code is loosely coupled, then there's no problem with > understanding it in isolation. If the code is highly coupled, then it is > hard to refactor it into a separate function, but that's a side-effect of > the original problem, namely the high degree of coupling. >
Different blocks of an if/elif/elif/elif/elif/end are never directly coupled to each other, since you know that only one of the blocks is gonna execute. The blocks inherently do not effect each other. What you really achieve by extracting the code from an inside an elif block into a method is decoupling the elif block from the code ABOVE the if. This in and of itself is a good thing, of course, because you get a nice clean namespace in the extracted method, and you make the coupling between the code ABOVE the if and the extracted method explicit by specifying which parameters get passed. And in the case of my original code, all seven methods that were extracted only depended on a single parameter, the variable I was calling "ast," so it was easy to dispatch them all using the same mechanism. (In my case I didn't achieve much in terms of cleaning the local namespace, since the only variable defined above the if/elif/elif/elif/end was "kind," but I did make my code less brittle to future changes.) I am not going to defend "if/elif/elif/elif/elif/end" too vigorously here. There are obvious advantages to extracting methods, even methods that only ever get called from one parent. I do not miss switch statements one bit in Python. I am little more ambivalent about anonymous methods. It pains me just a tiny bit whenever I have write code like this: dispatches = { 'dict': handle_dict, 'list': handle_list, 'attr': handle_attr, 'key': handle_key, 'as': handle_as, 'call': handle_call, } if kind in dispatches: return dispatches[kind](ast) else: raise Exception('unknown kind!') I have used the idiom that Simon suggested in an earlier post, shown below, but it is still brittle to name changes in a way that anonymous methods are not, because you can't break an inline anonymous method with a name change (the benefits on anonymity!!): try: method = getattr(self, 'do_' + kind) except AttributeError: raise Exception('unknown kind!') self.ast = ast return method() -- http://mail.python.org/mailman/listinfo/python-list