Ron Adam wrote: > Steven D'Aprano wrote: >> Er, maybe I'm misunderstanding something here, but surely the most >> obvious case is for default and special function arguments: >> >> def count_records(record_obj, start=0, end=None): >> if end == None: >> end = len(record_obj) >> if start == None: # this is not the default! >> # start at the current position >> start = record_obj.current >> n = 0 >> for rec in record_obj.data[start:end]: >> if not rec.isblank(): >> n += 1 >> return n
[snip] > You have three possible outcomes, > count all > count range > count using current index > count range from beginning to current > count range from current to end That makes four outcomes by my count. > The most consistent way to do this would be: > > def count_records(record_obj, start=0, end=len(record_obj)): That would work really well, except that it doesn't work at all. At the time the function is defined, record_obj doesn't exist, so there is no way of telling what it's length will be when the function is called. Here is a simpler example showing the problem: py> def func(s, start=0, end=len(s)): ... return s[start:end] ... Traceback (most recent call last): File "<stdin>", line 1, in ? NameError: name 's' is not defined The only way this strategy works is if there is a global variable s which defines a __len__ method. But then the default value of end will be fixed to the length of that global for all time (or at least until the module is reloaded). So given a pre-existing global variable, you get a class of hard-to-debug bugs: py> s = [0, 1, 2, 3] py> def func(s, start=0, end=len(s)): ... return s[start:end] ... py> func("function", start=1, end=5) # works correctly "unct" py> func("ant") # default works correctly here "ant" py> func("function") # default is broken here "func" py> s = "antidisestablishmentarianism" py> func(s) # default is broken even when s changed "anti" -- Steven. -- http://mail.python.org/mailman/listinfo/python-list