#🔒 Default argument persistence

12 messages · Page 1 of 1 (latest)

muted minnow
#

Good evening,

I’m seeing unexpected state persistence with a function like this:

def add_item(item, items=[]):
    items.append(item)
    return items

Calling it twice:

add_item("apple")
add_item("banana")

returns ["apple", "banana"] on the second call instead of ["banana"]. I expected the default list to be empty each time. Why does it persist and what's the canonical way to do this ?

echo turtleBOT
#

@muted minnow

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

iron leaf
#

the default is created and assigned exactly once: when the function is defined

#

that's actually a common foot gun and linters would flag it

#

the usual thing is to have a sentinel value like None as the default, and if items is none when called create a new list

muted minnow
#

Noted. Thank you very much

haughty rivet
quaint badge
#

Reference: https://stackoverflow.com/questions/1132941/

if you don't actually want this, then better not to expect a mutable parameter (default or not) in the first place, and better not to mutate it (i.e. if you return a value, then only do that). https://en.wikipedia.org/wiki/Command–query_separation

The standard library strongly abides by this principle, which is also exactly why e.g. you can't chain .append calls.

Command-query separation (CQS) is a principle of imperative computer programming. It was devised by Bertrand Meyer as part of his pioneering work on the Eiffel programming language.
It states that every method should either be a command that performs an action, or a query that returns data to the caller, but not both. In other words, asking a qu...

fickle island
#

take .pop() for example on lists, dicts and sets
there are many more examples where you need to do this

echo turtleBOT
#
Python help channel closed for inactivity

This help channel has been closed. Feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.