Excellent contributions. I'm going to try to (partially) consolidate what we've got.
REVIEW ======= I'll start by reviewing the situation regarding default arguments. There are two basic patterns for default arguments. The first is --- def fn(a=EXP): # body of function --- The second is --- def fn(a=None): if a is None: a = EXP # body of function --- Here, EXP is any Python expression. A fairly gotcha is to use a list, or some other mutable object, as EXP. This happens when you write --- def fn(a=[]): # body of function --- because then EXP = '[]' which will be evaluated just once, and every call fn() will be using the same list! To avoid this you should use the second pattern. I think there may be an example of this in the standard Python tutorial. (An aside. You probably need the second pattern if you EXP is, say, ([], []). Although technically immutable, this value has mutable members. And can't be hashed, or use as a dictionary key or element of a set.) WHEN TO USE None ================= If you want something mutable as the 'default argument' you have to use the second pattern. If your default argument is immutable then you can if you wish use the second pattern. But you don't have to use the second pattern. When you use the second pattern, the expression f(None) means 'create for me the default argument' (and raise an exception if there isn't one). Think about it. For immutable EXP, fn() is the same, whether fn is coded using the first pattern or the second. But the value of fn(None) depends very much on which pattern is used to code fn(). So here's the big conclusion (drum roll): === fn should be coded using the second pattern if we wish to pass None as a sentinel argument to fn. === SUMMARY ========= My suggestion was to use the second pattern to solve Peter O'Connor's original problem. It can be done now, but is a bit verbose, and looses useful information in help(fn). Brice Parent's suggestion was to introduce a keyword deferred, like so --- def fn(deferred a=EXP): # body of function --- which I like to think of as a syntactic shorthand for the second pattern. I sort of think we've now got a reasonable answer for Peter's problem. What do you think, Peter? And Brice, are you happy with my interpretation of your deferred keyword? --- Jonathan _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/