From 02e84cb34302bca589c97efe0051f4b9021577ae Mon Sep 17 00:00:00 2001 From: Paul McCarthy <pauldmccarthy@gmail.com> Date: Thu, 1 Feb 2018 17:00:56 +0000 Subject: [PATCH] Little more work on args prac --- .../function_inputs_and_outputs.ipynb | 64 +++++++++++++++++-- .../function_inputs_and_outputs.md | 36 ++++++++++- 2 files changed, 94 insertions(+), 6 deletions(-) diff --git a/advanced_topics/function_inputs_and_outputs.ipynb b/advanced_topics/function_inputs_and_outputs.ipynb index 335cb06..2306f9e 100644 --- a/advanced_topics/function_inputs_and_outputs.ipynb +++ b/advanced_topics/function_inputs_and_outputs.ipynb @@ -180,10 +180,66 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "> Pitfall: mutable argument values\n", - "\n", - "\n", - "You can see here that" + "__WARNING:__ _Never_ define a function with a mutable default value, such as a\n", + "`list`, `dict` or other non-primitive type. Let's see what happens when we do:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def badfunc(a=[]):\n", + " a.append('end of sequence')\n", + " output = ', '.join([str(elem) for elem in a])\n", + " print(output)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With this function, all is well and good if we pass in our own value for `a`:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "badfunc([1, 2, 3, 4])\n", + "badfunc([2, 4, 6])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "But what happens when we let `badfunc` use the default value for `a`?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "badfunc()\n", + "badfunc()\n", + "badfunc()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This happens because default argument values are created when the function is\n", + "defined, and will persist for the duration of your program. So in this\n", + "example, the default value for `a`, a Python `list`, gets created when\n", + "`badfunc` is defined, and hangs around for the lifetime of the `badfunc`\n", + "function!" ] } ], diff --git a/advanced_topics/function_inputs_and_outputs.md b/advanced_topics/function_inputs_and_outputs.md index 0a5ee93..5777da1 100644 --- a/advanced_topics/function_inputs_and_outputs.md +++ b/advanced_topics/function_inputs_and_outputs.md @@ -106,7 +106,39 @@ myfunc(c=300) ``` -> Pitfall: mutable argument values +__WARNING:__ _Never_ define a function with a mutable default value, such as a +`list`, `dict` or other non-primitive type. Let's see what happens when we do: -You can see here that +``` +def badfunc(a=[]): + a.append('end of sequence') + output = ', '.join([str(elem) for elem in a]) + print(output) +``` + + +With this function, all is well and good if we pass in our own value for `a`: + + +``` +badfunc([1, 2, 3, 4]) +badfunc([2, 4, 6]) +``` + + +But what happens when we let `badfunc` use the default value for `a`? + + +``` +badfunc() +badfunc() +badfunc() +``` + + +This happens because default argument values are created when the function is +defined, and will persist for the duration of your program. So in this +example, the default value for `a`, a Python `list`, gets created when +`badfunc` is defined, and hangs around for the lifetime of the `badfunc` +function! \ No newline at end of file -- GitLab