Last active
August 27, 2019 17:53
-
-
Save brydavis/6e67ee55da925787de7969c78414ea43 to your computer and use it in GitHub Desktop.
Examples creating and using custom context managers in Python
This file contains 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": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Context Manager Examples" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 27, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"some external work\n", | |
"initializing context\n", | |
"entering context\n", | |
"some internal work\n", | |
"5\n", | |
"some more internal work\n", | |
"exiting context\n", | |
"some more external work\n" | |
] | |
} | |
], | |
"source": [ | |
"class C:\n", | |
" def __init__(self):\n", | |
" print(\"initializing context\")\n", | |
" self.x = 0\n", | |
"\n", | |
" def __enter__(self):\n", | |
" print(\"entering context\")\n", | |
" self.x = 5\n", | |
" return self\n", | |
" \n", | |
" def add(self, y):\n", | |
" self.x + y\n", | |
" \n", | |
" def subtract(self, y):\n", | |
" self.x - y\n", | |
"\n", | |
" \n", | |
" def __exit__(self, exit_type, exit_val, exit_tb):\n", | |
" print(\"exiting context\")\n", | |
" \n", | |
" \n", | |
"print(\"some external work\")\n", | |
"with C() as c: # both init and enter happen here\n", | |
" print(\"some internal work\")\n", | |
" print(c.x)\n", | |
" print(\"some more internal work\")\n", | |
" # exiting happen at the end\n", | |
"print(\"some more external work\")\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"__init__ code here\n", | |
"__enter__ code goes here\n", | |
"something\n", | |
"__exit__ cleanup goes here\n" | |
] | |
} | |
], | |
"source": [ | |
"from contextlib import contextmanager\n", | |
"\n", | |
"@contextmanager\n", | |
"def context(boolean):\n", | |
" print(\"__init__ code here\")\n", | |
" try:\n", | |
" print(\"__enter__ code goes here\")\n", | |
" yield object()\n", | |
" except Exception as e:\n", | |
" print(\"errors handled here\")\n", | |
" if not boolean:\n", | |
" raise e\n", | |
" finally:\n", | |
" print(\"__exit__ cleanup goes here\")\n", | |
" \n", | |
" \n", | |
"with context(True) as c:\n", | |
" print(\"something\")" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 9, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"some external work\n", | |
"initializing context\n", | |
"entering context\n", | |
"some internal work\n", | |
"5\n", | |
"some more internal work\n", | |
"exiting context\n", | |
"some more external work\n" | |
] | |
} | |
], | |
"source": [ | |
"from contextlib import contextmanager\n", | |
"\n", | |
"@contextmanager\n", | |
"def C(boolean=False):\n", | |
" print(\"initializing context\") \n", | |
" try:\n", | |
" print(\"entering context\")\n", | |
" data = {\n", | |
" \"x\": 5\n", | |
" }\n", | |
" obj = type('', (object,), data)()\n", | |
" yield obj\n", | |
" except Exception as e:\n", | |
" print(\"errors handled here\")\n", | |
" if not boolean:\n", | |
" raise e\n", | |
" finally:\n", | |
" print(\"exiting context\")\n", | |
" \n", | |
"\n", | |
" \n", | |
"print(\"some external work\")\n", | |
"with C() as c: # both init and enter happen here\n", | |
" print(\"some internal work\")\n", | |
" print(c.x)\n", | |
" print(\"some more internal work\")\n", | |
" # exiting happen at the end\n", | |
"print(\"some more external work\") \n", | |
" " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.7.4" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Note that in the
__exit__
method using the class way:exit_type
is the exit typeexit_val
is the exit valueexit_tb
is the exit tracebackTry printed them out if you want to see what they look like.