Created
May 5, 2016 23:16
-
-
Save minrk/2f717c257ce7aa37dc082b4141204d7b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "# Multiple namespaces for IPython\n\n<blockquote class=\"twitter-tweet\" data-partner=\"tweetdeck\"><p lang=\"en\" dir=\"ltr\">Feature request for <a href=\"https://twitter.com/ProjectJupyter\">@ProjectJupyter</a>: Define multiple namespaces within the same notebook (without using functions).</p>— Juan Manuel Caicedo (@cavorite) <a href=\"https://twitter.com/cavorite/status/728354406723297281\">May 5, 2016</a></blockquote>\n<script async src=\"//platform.twitter.com/widgets.js\" charset=\"utf-8\"></script>\n\nThis is a simple proof-of-concept implementation of switching namespaces via magics. The key points we need:\n\n1. IPython's namespace is stored on the `.user_ns` attribute on the IPython instance\n2. IPython relies on some globals in the user ns created with `ip.init_user_ns`\n3. A namespace in Python is a dict\n\n" | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "First, we create a dict of namespaces by name on IPython, and save the initial value:" | |
}, | |
{ | |
"metadata": { | |
"trusted": true, | |
"collapsed": true | |
}, | |
"cell_type": "code", | |
"source": "ip = get_ipython()\nip.namespaces = {}\nip._original_user_ns = ip.user_ns", | |
"execution_count": 1, | |
"outputs": [] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "Next, we define a `%ns` line magic for switching namespaces by name:\n\nWe use ChainMap so that globals that IPython defines, such as In, Out, etc. are available no matter what namespace we switch to:" | |
}, | |
{ | |
"metadata": { | |
"trusted": true, | |
"collapsed": false | |
}, | |
"cell_type": "code", | |
"source": "from collections import ChainMap\n\ndef set_namespace(name):\n \"\"\"Line magic for switching namespaces:\n \n %ns foo\n a = 5\n\n %ns bar\n a = 10\n\n %ns foo\n print(a)\n # 10\n \"\"\"\n if name not in ip.namespaces:\n ip.namespaces[name] = ChainMap({}, ip._original_user_ns)\n ip.user_ns = ip.namespaces[name]\n\nip.register_magic_function(set_namespace, magic_name='ns')\nset_namespace('default')", | |
"execution_count": 2, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true, | |
"collapsed": false | |
}, | |
"cell_type": "code", | |
"source": "%ns foo\n\na = 5\n\n%ns bar\n\na = 10\n\n%ns foo\n\na", | |
"execution_count": 3, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"data": { | |
"text/plain": "5" | |
}, | |
"execution_count": 3, | |
"output_type": "execute_result" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true, | |
"collapsed": false | |
}, | |
"cell_type": "code", | |
"source": "ip.namespaces['foo']['a']", | |
"execution_count": 4, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"data": { | |
"text/plain": "5" | |
}, | |
"execution_count": 4, | |
"output_type": "execute_result" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true, | |
"collapsed": false | |
}, | |
"cell_type": "code", | |
"source": "ip.namespaces['bar']['a']", | |
"execution_count": 5, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"data": { | |
"text/plain": "10" | |
}, | |
"execution_count": 5, | |
"output_type": "execute_result" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true, | |
"collapsed": false | |
}, | |
"cell_type": "code", | |
"source": "%whos", | |
"execution_count": 6, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": "Variable Type Data/Info\n-------------------------------------\nChainMap ABCMeta <class 'collections.ChainMap'>\na int 5\nset_namespace function <function set_namespace at 0x109866d90>\n" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true, | |
"collapsed": false | |
}, | |
"cell_type": "code", | |
"source": "%ns bar\n%whos", | |
"execution_count": 7, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": "Variable Type Data/Info\n-------------------------------------\nChainMap ABCMeta <class 'collections.ChainMap'>\na int 10\nset_namespace function <function set_namespace at 0x109866d90>\n" | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "We can also make a cell magic for running a whole cell in a given namespace,\nthen switching back to whatever was already active:" | |
}, | |
{ | |
"metadata": { | |
"trusted": true, | |
"collapsed": true | |
}, | |
"cell_type": "code", | |
"source": "def namespace_cell(name, cell):\n \"\"\"Cell magic for running a single cell in a given namespace\n \n %%ns foo\n a = 5\n \"\"\"\n save_ns = ip.user_ns\n set_namespace(name)\n try:\n ip.run_cell(cell)\n finally:\n ip.user_ns = save_ns\n \n \nip.register_magic_function(namespace_cell, magic_kind='cell', magic_name='ns')", | |
"execution_count": 8, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true, | |
"collapsed": false | |
}, | |
"cell_type": "code", | |
"source": "%%ns cellns\n\na = 'hello,'\nprint(a * 2)", | |
"execution_count": 9, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": "hello,hello,\n" | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "This didn't affect the running namespace:" | |
}, | |
{ | |
"metadata": { | |
"trusted": true, | |
"collapsed": false | |
}, | |
"cell_type": "code", | |
"source": "a", | |
"execution_count": 10, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"data": { | |
"text/plain": "10" | |
}, | |
"execution_count": 10, | |
"output_type": "execute_result" | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "But we can recall the cell namespace:" | |
}, | |
{ | |
"metadata": { | |
"trusted": true, | |
"collapsed": false | |
}, | |
"cell_type": "code", | |
"source": "%%ns cellns\na", | |
"execution_count": 11, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"data": { | |
"text/plain": "'hello,'" | |
}, | |
"execution_count": 11, | |
"output_type": "execute_result" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true, | |
"collapsed": false | |
}, | |
"cell_type": "code", | |
"source": "for name, ns in ip.namespaces.items():\n print(name, ns.get('a', 'undefined'))", | |
"execution_count": 12, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": "foo 5\nbar 10\ndefault undefined\ncellns hello,\n" | |
} | |
] | |
} | |
], | |
"metadata": { | |
"widgets": { | |
"state": {}, | |
"version": "1.0.0" | |
}, | |
"kernelspec": { | |
"name": "python3", | |
"display_name": "Python 3", | |
"language": "python" | |
}, | |
"language_info": { | |
"mimetype": "text/x-python", | |
"file_extension": ".py", | |
"pygments_lexer": "ipython3", | |
"nbconvert_exporter": "python", | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"version": "3.5.1", | |
"name": "python" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 1 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment