51042-notes/more-decorators.ipynb
2024-10-27 19:16:17 -05:00

284 lines
6.3 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "02e68cf1",
"metadata": {},
"source": [
"# More Decorator Examples\n",
"\n",
"Some additional examples beyond what is in 08.decorators."
]
},
{
"cell_type": "markdown",
"id": "b985a33b",
"metadata": {},
"source": [
"## Modifying Arguments within newfunc"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "31c291f2",
"metadata": {},
"outputs": [],
"source": [
"def reverse_args(func):\n",
" def newfunc(*args):\n",
" # within newfunc we are able to write whatever we'd like\n",
" # we could decide that we want to reverse the arguments\n",
" reversed_args = reversed(args)\n",
" return func(*reversed_args)\n",
" return newfunc\n",
"\n",
"\n",
"@reverse_args\n",
"def print_args(*args):\n",
" for arg in args:\n",
" print(arg)"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "413cfac8",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"3\n",
"2\n",
"1\n"
]
}
],
"source": [
"print_args(1, 2, 3)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "95e01cf9",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.2"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"@reverse_args\n",
"def divide(a, b):\n",
" return a / b\n",
"\n",
"divide(10, 2)"
]
},
{
"cell_type": "markdown",
"id": "d055880d",
"metadata": {},
"source": [
"## Example: Authorization"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "1590c5de",
"metadata": {},
"outputs": [],
"source": [
"# perhaps we want a function that checks if a user can perform an action\n",
"def auth_required(func):\n",
" \n",
" # list of allowed users. in practice, we'd look this up in a database\n",
" allowed_users = (\"lauren\", \"mitch\")\n",
" \n",
" def newfunc(*args, **kwargs):\n",
" # here, we're actually using an argument within newfunc\n",
" # by checking if it is in the kwargs dictionary\n",
" if kwargs.get(\"auth_user\") in allowed_users:\n",
" func(*args, **kwargs)\n",
" else:\n",
" print(\"ACCESS DENIED\")\n",
" return newfunc\n",
"\n",
"# these functions must also accept auth_user so that the above call to func(*args, **kwargs)\n",
"# doesn't send an invalid parameter through\n",
"@auth_required\n",
"def withdraw_funds(account, amount, auth_user):\n",
" print(f\"withdrew {amount} funds from account={account}\")\n",
"\n",
"@auth_required\n",
"def delete_account(account, auth_user):\n",
" print(\"deleted\", account)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "f9e8bcd0",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"withdrew 100 funds from account=jim\n"
]
}
],
"source": [
"withdraw_funds(\"jim\", 100, auth_user=\"lauren\")"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "77a82ae4",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"ACCESS DENIED\n"
]
}
],
"source": [
"delete_account(\"kevin\", auth_user=\"jim\")"
]
},
{
"cell_type": "markdown",
"id": "cf9a611a",
"metadata": {},
"source": [
"## Modifying Keyword Parameters"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "90161162",
"metadata": {},
"outputs": [],
"source": [
"# if we didn't want auth_user to be passed through, we'd make a small modification to newfunc\n",
"\n",
"def auth_required(func): \n",
" allowed_users = (\"lauren\", \"mitch\")\n",
" \n",
" def newfunc(*args, auth_user, **kwargs):\n",
" # newfunc now requires auth_user, and passes through all *other* parameters\n",
" if auth_user in allowed_users:\n",
" func(*args, **kwargs)\n",
" else:\n",
" print(\"ACCESS DENIED\")\n",
" return newfunc\n",
"\n",
"# auth_user is no longer seen in the definition of these functions \n",
"# but it can be passed in since the newfunc returned from auth_required accepts it\n",
"@auth_required\n",
"def withdraw_funds(account, amount):\n",
" print(f\"withdrew {amount} funds from account={account}\")\n",
"\n",
"@auth_required\n",
"def delete_account(account):\n",
" print(\"deleted\", account)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "ee4cabe7",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"withdrew 100 funds from account=jim\n"
]
}
],
"source": [
"withdraw_funds(\"jim\", 100, auth_user=\"lauren\")"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "a22a86d9",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"ACCESS DENIED\n"
]
}
],
"source": [
"delete_account(\"kevin\", auth_user=\"jim\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "dca4b1ec",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"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.10.15"
},
"toc": {
"base_numbering": 1,
"nav_menu": {},
"number_sections": false,
"sideBar": true,
"skip_h1_title": false,
"title_cell": "Table of Contents",
"title_sidebar": "Contents",
"toc_cell": false,
"toc_position": {},
"toc_section_display": true,
"toc_window_display": false
}
},
"nbformat": 4,
"nbformat_minor": 5
}