On Jan 30, 2012, at 7:00 PM, Steven D'Aprano wrote: > On Mon, 30 Jan 2012 12:41:00 -0500, Charles Yeomans wrote: > >> To catch more than one exception type in an except block, one writes >> >> except (A, B, C) as e: >> >> I'm wondering why it was decided to match tuples, but not lists: >> >> except [A, B, C] as e: > > Simplicity. > > If you also allow lists, then why not allow arbitrary sequences? What > about iterators, do you allow them? That could be awkward, because > iterators can only be run through once. Dictionaries are also iterable, > so once you allow arbitrary iterables, you get dicts. The whole thing > becomes a mess. Better to keep it simple and only allow a single > canonical collection type, and in Python, that type is tuple, not list. > > Tuples are that canonical collection type because they have a number of > desirable properties: > > - Tuples are small and memory efficient, using the smallest amount of > memory needed to hold their items. Lists typically carry a block of > spare memory, to make insertions fast. > > - Consequently the Python virtual machine can create them rapidly and > efficiently. > > - Tuples are immutable, so you don't have to worry about passing one to a > function and having the function modify it behind your back. > > - Tuples are ordered, for the times where that matters. > > - Since the typical use-case is to iterate over the items in fixed order, > there's no need to pay the extra expense for a dict or set. > > - Tuples are simple to write: in general you only need commas between > items. Sometimes, to avoid ambiguity or change the precedence of > calculation, you also need round brackets (parentheses for Americans). > Except clauses are one of those times. > > - Frozensets and sets are ruled out for historical reasons: they didn't > exist until Python 2.3. Besides, which would you rather write? > > ("abc", "def") > frozenset([abc", "def"]) > > - Sets and lists are ruled out because they are mutable, both require > much more memory, and sets have a heavier computational burden. > > > >> The latter makes more sense semantically to me -- "catch all exception >> types in a list" as opposed to "catch this single thing composed of >> three exception types". > > Then you are labouring under a misunderstanding. You're not catching a > tuple, because tuples are never thrown. You're catching any of the > exceptions that are contained in that tuple. > > Both lists and tuples *are* single things in themselves. Both lists and > tuples are containers: > > A list is a single thing that contains other things. > > A tuple is a single thing that contains other things. >
I don't think of a tuple as a container, and I don't think it a misunderstanding on my part to think this. But I am aware that it is common to use tuples as immutable lists. I don't see that performance was really a consideration, given that one can use any expression in an except statement -- except IOError if today == 'Monday' else OSError as e or L = [] try: #code except tuple(L) as e: pass except Exception, e: L.append(e.__class__) In any case, though I appreciate your attempt at a post hoc justification, I was hoping for a positive explanation. Charles Yeomans -- http://mail.python.org/mailman/listinfo/python-list