diff --git a/.ipynb_checkpoints/not_so_obvious_python_stuff-checkpoint.ipynb b/.ipynb_checkpoints/not_so_obvious_python_stuff-checkpoint.ipynb
index 171353f..85df945 100644
--- a/.ipynb_checkpoints/not_so_obvious_python_stuff-checkpoint.ipynb
+++ b/.ipynb_checkpoints/not_so_obvious_python_stuff-checkpoint.ipynb
@@ -1,7 +1,7 @@
{
"metadata": {
"name": "",
- "signature": "sha256:faa74a34746bf250ef2d72e308074083ee5e60789203d70f630f8c67a709e6fe"
+ "signature": "sha256:06e485535e22c756262f09d4477108b57d0fa1029f9831ee77a177267f5afc7f"
},
"nbformat": 3,
"nbformat_minor": 0,
@@ -46,7 +46,8 @@
"- [Don't use mutable objects as default arguments for functions!](#def_mutable_func)\n",
"- [Be aware of the consuming generator](#consuming_generator)\n",
"- [`bool` is a subclass of `int`](#bool_int)\n",
- "- [About lambda and closures-in-a-loop pitfall](#lambda_closure)"
+ "- [About lambda and closures-in-a-loop pitfall](#lambda_closure)\n",
+ "- [Python's LEGB scope resolution and the keywords `global` and `nonlocal`](#python_legb)"
]
},
{
@@ -594,7 +595,9 @@
"\n",
"## About lambda and closures-in-a-loop pitfall\n",
"\n",
- "The following example illustrates how the (last) `lambda` is being reused:"
+ "The following example illustrates how the (last) `lambda` is being reused:\n",
+ "\n",
+ "(Original source: [http://openhome.cc/eGossip/Blog/UnderstandingLambdaClosure3.html](http://openhome.cc/eGossip/Blog/UnderstandingLambdaClosure3.html))"
]
},
{
@@ -654,13 +657,167 @@
],
"prompt_number": 25
},
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "
\n",
+ "
\n",
+ "\n",
+ "\n",
+ "## Python's LEGB scope resolution and the keywords `global` and `nonlocal`"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "There is nothing particularly surprising about Python's LEGB scope resolution (Local -> Enclosed -> Global -> Built-in), but it is still useful to take a look at some examples!"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### `global` vs. `local`\n",
+ "\n",
+ "According to the LEGB rule, Python will first look for a variable in the local scope. So if we set the variable `x = 1` in the `local`ly in the function's scope, it won't have an effect on the `global` `x`."
+ ]
+ },
{
"cell_type": "code",
"collapsed": false,
- "input": [],
+ "input": [
+ "x = 0\n",
+ "def in_func():\n",
+ " x = 1\n",
+ " print('in_func:', x)\n",
+ " \n",
+ "in_func()\n",
+ "print('global:', x)"
+ ],
"language": "python",
"metadata": {},
- "outputs": []
+ "outputs": [
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "in_func: 1\n",
+ "global: 0\n"
+ ]
+ }
+ ],
+ "prompt_number": 33
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "If we want to modify the `global` x via a function, we can simply use the `global` keyword to import the variable into the function's scope:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "x = 0\n",
+ "def in_func():\n",
+ " global x\n",
+ " x = 1\n",
+ " print('in_func:', x)\n",
+ " \n",
+ "in_func()\n",
+ "print('global:', x)"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "in_func: 1\n",
+ "global: 1\n"
+ ]
+ }
+ ],
+ "prompt_number": 34
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### `local` vs. `enclosed`\n",
+ "\n",
+ "Now, let us take a look at `local` vs. `enclosed`. Here, we set the variable `x = 1` in the `outer` function and set `x = 1` in the enclosed function `inner`. Since `inner` looks in the local scope first, it won't modify `outer`'s `x`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "def outer():\n",
+ " x = 1\n",
+ " print('outer before:', x)\n",
+ " def inner():\n",
+ " x = 2\n",
+ " print(\"inner:\", x)\n",
+ " inner()\n",
+ " print(\"outer after:\", x)\n",
+ "outer()"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "outer before: 1\n",
+ "inner: 2\n",
+ "outer after: 1\n"
+ ]
+ }
+ ],
+ "prompt_number": 36
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Here is where the `nonlocal` keyword comes in handy - it allows us to modify the `x` variable in the `enclosed` scope:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "def outer():\n",
+ " x = 1\n",
+ " print('outer before:', x)\n",
+ " def inner():\n",
+ " nonlocal x\n",
+ " x = 2\n",
+ " print(\"inner:\", x)\n",
+ " inner()\n",
+ " print(\"outer after:\", x)\n",
+ "outer()"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "outer before: 1\n",
+ "inner: 2\n",
+ "outer after: 2\n"
+ ]
+ }
+ ],
+ "prompt_number": 35
}
],
"metadata": {}
diff --git a/not_so_obvious_python_stuff.ipynb b/not_so_obvious_python_stuff.ipynb
index 171353f..85df945 100644
--- a/not_so_obvious_python_stuff.ipynb
+++ b/not_so_obvious_python_stuff.ipynb
@@ -1,7 +1,7 @@
{
"metadata": {
"name": "",
- "signature": "sha256:faa74a34746bf250ef2d72e308074083ee5e60789203d70f630f8c67a709e6fe"
+ "signature": "sha256:06e485535e22c756262f09d4477108b57d0fa1029f9831ee77a177267f5afc7f"
},
"nbformat": 3,
"nbformat_minor": 0,
@@ -46,7 +46,8 @@
"- [Don't use mutable objects as default arguments for functions!](#def_mutable_func)\n",
"- [Be aware of the consuming generator](#consuming_generator)\n",
"- [`bool` is a subclass of `int`](#bool_int)\n",
- "- [About lambda and closures-in-a-loop pitfall](#lambda_closure)"
+ "- [About lambda and closures-in-a-loop pitfall](#lambda_closure)\n",
+ "- [Python's LEGB scope resolution and the keywords `global` and `nonlocal`](#python_legb)"
]
},
{
@@ -594,7 +595,9 @@
"\n",
"## About lambda and closures-in-a-loop pitfall\n",
"\n",
- "The following example illustrates how the (last) `lambda` is being reused:"
+ "The following example illustrates how the (last) `lambda` is being reused:\n",
+ "\n",
+ "(Original source: [http://openhome.cc/eGossip/Blog/UnderstandingLambdaClosure3.html](http://openhome.cc/eGossip/Blog/UnderstandingLambdaClosure3.html))"
]
},
{
@@ -654,13 +657,167 @@
],
"prompt_number": 25
},
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "
\n",
+ "
\n",
+ "\n",
+ "\n",
+ "## Python's LEGB scope resolution and the keywords `global` and `nonlocal`"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "There is nothing particularly surprising about Python's LEGB scope resolution (Local -> Enclosed -> Global -> Built-in), but it is still useful to take a look at some examples!"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### `global` vs. `local`\n",
+ "\n",
+ "According to the LEGB rule, Python will first look for a variable in the local scope. So if we set the variable `x = 1` in the `local`ly in the function's scope, it won't have an effect on the `global` `x`."
+ ]
+ },
{
"cell_type": "code",
"collapsed": false,
- "input": [],
+ "input": [
+ "x = 0\n",
+ "def in_func():\n",
+ " x = 1\n",
+ " print('in_func:', x)\n",
+ " \n",
+ "in_func()\n",
+ "print('global:', x)"
+ ],
"language": "python",
"metadata": {},
- "outputs": []
+ "outputs": [
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "in_func: 1\n",
+ "global: 0\n"
+ ]
+ }
+ ],
+ "prompt_number": 33
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "If we want to modify the `global` x via a function, we can simply use the `global` keyword to import the variable into the function's scope:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "x = 0\n",
+ "def in_func():\n",
+ " global x\n",
+ " x = 1\n",
+ " print('in_func:', x)\n",
+ " \n",
+ "in_func()\n",
+ "print('global:', x)"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "in_func: 1\n",
+ "global: 1\n"
+ ]
+ }
+ ],
+ "prompt_number": 34
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### `local` vs. `enclosed`\n",
+ "\n",
+ "Now, let us take a look at `local` vs. `enclosed`. Here, we set the variable `x = 1` in the `outer` function and set `x = 1` in the enclosed function `inner`. Since `inner` looks in the local scope first, it won't modify `outer`'s `x`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "def outer():\n",
+ " x = 1\n",
+ " print('outer before:', x)\n",
+ " def inner():\n",
+ " x = 2\n",
+ " print(\"inner:\", x)\n",
+ " inner()\n",
+ " print(\"outer after:\", x)\n",
+ "outer()"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "outer before: 1\n",
+ "inner: 2\n",
+ "outer after: 1\n"
+ ]
+ }
+ ],
+ "prompt_number": 36
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Here is where the `nonlocal` keyword comes in handy - it allows us to modify the `x` variable in the `enclosed` scope:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "def outer():\n",
+ " x = 1\n",
+ " print('outer before:', x)\n",
+ " def inner():\n",
+ " nonlocal x\n",
+ " x = 2\n",
+ " print(\"inner:\", x)\n",
+ " inner()\n",
+ " print(\"outer after:\", x)\n",
+ "outer()"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "outer before: 1\n",
+ "inner: 2\n",
+ "outer after: 2\n"
+ ]
+ }
+ ],
+ "prompt_number": 35
}
],
"metadata": {}