-1

So I know that "mutable default arguments" are a 'feature' of Python that can often cause unexpected behaviour (there's an interesting Stack Overflow page about here: "Least Astonishment" and the Mutable Default Argument).

And I know that the usual solution is to set arg=None in the function signature, and then set the value within the function, like if arg is None: arg = [] #or whatever (cf. What is the pythonic way to avoid default parameters that are empty lists?, Why does using `arg=None` fix Python's mutable default argument issue?).

But what if I want to allow None to be explicitly specified? I could use a string that explains what we're doing, ie. make the default arg='none_specified', and then do if arg=='unspecified': arg = []. But that seems a little ugly.

Is there a Pythonic solution to this?

Peter Prescott
  • 646
  • 6
  • 14
  • I'm not sure what you're asking. How does the first part (mutable default arguments) connect with the second (allowing to pass `None`…?)? – deceze May 10 '22 at 13:48
  • *Why do you actually need the default argument to be mutable*? Almost certainly this is only because of some convenience for your algorithm. After all, the *reason it matters* whether a parameter is mutable is because a mutable argument would... be mutated by calling the function; and the *entire point* of a default argument is to cover the case where there *isn't* a passed-in argument to get mutated. – Karl Knechtel May 10 '22 at 13:50
  • @deceze because the usual workaround for the problem of mutable default arguments (where the mutation to that argument affects subsequent calls) is to use `None` and handle it as a special case. The point is that the code can no longer distinguish whether the caller omitted the argument, or *explicitly* specified `None`. – Karl Knechtel May 10 '22 at 13:51
  • @deceze I'm trying to fixa bug that is caused by hidden state issues, because a default argument is initialized when a class is first instantiated, and then passed to subsequent instances of the class, which can change the object. to fix it, I want to set `arg=None`, and initialize the object within. But the codebase also includes cases (tests) where the class is instantiated deliberately with `arg=None` because `None` is desired. – Peter Prescott May 10 '22 at 13:52
  • @PeterPrescott does it really matter which of those 2 happened? Is (or better question, ***should***) the program behave differently with explicit pass of `None` vs default `None`? – matszwecja May 10 '22 at 13:54
  • 1
    As the dupe covers, use a sentinel other than None. Create a sentinel just for this purpose, so there is no reason anyone should pass it explicitly as an argument. – khelwood May 10 '22 at 13:54
  • I get that you want to pass `None` and distinguish it from not passing an argument. What I don't understand is what that has to do with mutable default arguments. – deceze May 10 '22 at 13:55
  • @deceze because usual solution for *defaut* mutable arguments is a default of `None` and setting it to "actual" default argument which is a mutable object during the runtime of a function. – matszwecja May 10 '22 at 13:58
  • I don't need the default argument to be mutable, I'm trying to fix the problems caused by it being so. And yes, the duplicate answers my question. Thankyou! – Peter Prescott May 10 '22 at 13:58

0 Answers0