Stream: python
Topic: basic python
René Spronk (Jul 09 2020 at 16:44):
def pp(a, b=None):
print(b)
pp('a')
pp('a',b='hello')
pp('a')
Outputs None, 'hello', None. (as one would expect)
But I seem to have the situation whereby after pp('a',b='hello') all pp('a') calls afterwards regard b as being 'hello'. Any thoughts as to what might cause that to happen?
Jean Duteau (Jul 09 2020 at 16:54):
what do you mean "regard b as being 'hello'"? the fact that the third pp('a') prints None means that b doesn't have a value.
Josh Mandel (Jul 09 2020 at 17:50):
Your example and your description seem to contradict one another :-)
Josh Mandel (Jul 09 2020 at 17:50):
Maybe create a runnable example with something like https://notebooks.azure.com/ and share a link?
Josh Mandel (Jul 09 2020 at 17:50):
(deleted)
Carl Anderson (Jul 09 2020 at 20:36):
The google python style guide recommends against using mutable object types as default parameters.
Default arguments are evaluated once at module load time. This may cause problems if the argument is a mutable object such as a list or a dictionary. If the function modifies the object (e.g., by appending an item to a list), the default value is modified.
So, if you're seeing this with an immutable type like a string, that would be odd. But if it's an instance of something mutable, that might explain it.
Ilya Beda (Jul 10 2020 at 03:14):
Hi @René Spronk
>>> def pp(a,b='hello'):
... print(b)
...
>>> pp(1)
hello
>>> pp(1,2)
2
>>> pp(1)
hello
Your example works fine.
However, if you mutate default argument value it changes permanently.
>>> def pp(a,b={}):
... b[a] = a
... print(b)
...
>>> pp(1,{})
{1: 1}
>>> pp(2)
{2: 2}
>>> pp(3)
{2: 2, 3: 3}
>>> pp(4, {})
{4: 4}
>>> pp(5)
{2: 2, 3: 3, 5: 5}
>>>
René Spronk (Jul 10 2020 at 07:50):
Thanks - as it turned this was the classic 'by reference' vs 'by value' issue - using a global dict in a procedure, assigning a local variable name to a part of that global dict, modification of the local variable (and hence: of the global). Solved it by casting the gobal to dict() which forces a copy by value. (I wrote my own FHIR/REST module, just to learn Py, not because I'd do a better job than some of the libraries out there - I'm a trainer, not a programmer).
Last updated: Apr 12 2022 at 19:14 UTC