{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## 定义数据类" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "User(username='100gle', password='password', email='email@example.com', is_vip=False)" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import attrs\n", "\n", "\n", "@attrs.define\n", "class User:\n", " username: str\n", " password: str\n", " email: str\n", " is_vip: bool = False\n", "\n", "User(\"100gle\", \"password\", email=\"email@example.com\")" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "User(username='100gle', password=***, email='email@example.com')" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@attrs.define\n", "class User:\n", " username: str\n", " password: str = attrs.field(repr=lambda v: \"***\")\n", " email: str\n", " is_vip: bool = attrs.field(default=False, repr=False)\n", "\n", "User(\"100gle\", \"password\", email=\"email@example.com\")" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "from datetime import datetime\n", "\n", "import attrs\n", "\n", "\n", "@attrs.define\n", "class User:\n", " username: str\n", " email: str\n", " _password: str = attrs.field(repr=lambda v: \"***\")\n", " _is_vip: bool = attrs.field(init=False, default=False, repr=False)\n", " _recent_login_at: datetime = attrs.field(init=False, default=datetime.now())" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "User(username='100gle', email='email@example.com', _password=***, _recent_login_at=datetime.datetime(2022, 11, 19, 10, 44, 48, 848285))" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "User(\"100gle\", email=\"email@example.com\", password=\"password\")" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "from datetime import datetime\n", "\n", "import attr\n", "\n", "\n", "@attr.s\n", "class User:\n", " username = attr.ib(type=str)\n", " email = attr.ib(type=str)\n", " _password = attr.ib(repr=lambda v: \"***\")\n", " _is_vip = attr.ib(default=False, repr=False)\n", " _recent_login_at = attr.ib(init=False, default=datetime.now())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 自定义字段校验逻辑" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "class LimitError(Exception):\n", " pass\n", "\n", "\n", "@attrs.define\n", "class User:\n", " username: str\n", " email: str = attrs.field()\n", " _password: str = attrs.field(repr=lambda v: \"***\")\n", " _is_vip: bool = attrs.field(default=False, repr=False)\n", " _recent_login_at: datetime = attrs.field(init=False, default=datetime.now())\n", "\n", " @email.validator\n", " def _check_email(self, attribute, value: str):\n", " if not \"@\" in value:\n", " raise ValueError(\"invalid email that doesn't contains an '@' symbol\")\n", "\n", " if len(value) >= 15:\n", " raise LimitError(\"email out of the max length of 15 chars\")\n", "\n", " return value" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "# User(\"100gle\", email=\"email#example.com\", password=\"password\") # raise ValueError here!" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "import attrs\n", "\n", "class LimitError(Exception):\n", " pass\n", "\n", "def check_email_validation(instance, attribute, value: str):\n", " if not \"@\" in value:\n", " raise ValueError(\"invalid email that doesn't contains an '@' symbol\")\n", "\n", "\n", "def check_email_length(instance, attribute, value: str):\n", " if len(value) >= 15:\n", " raise LimitError(\"email out of the max length of 15 chars\")\n", "\n", "@attrs.define\n", "class User:\n", " username: str\n", " email: str = attrs.field(\n", " validator=[\n", " check_email_validation,\n", " check_email_length,\n", " ]\n", " )\n", " _password: str = attrs.field(repr=lambda v: \"***\")\n", " _is_vip: bool = attrs.field(default=False, repr=False)\n", " _recent_login_at: datetime = attrs.field(init=False, default=datetime.now())\n", "\n", " @email.validator\n", " def _check_email_suffix(self, attribute, value: str):\n", " if not value.endswith(\"com\"):\n", " raise ValueError(\"invalid domain\")\n" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "# User(\"100gle\", email=\"email#example.com\", password=\"password\") # raise ValueError here!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 自定义转换器" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "@attrs.define\n", "class C:\n", " x: int = attrs.field(converter=int)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "o = C(\"1\")\n", "o.x\n" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "int" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(o.x)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "from datetime import datetime\n", "\n", "import attrs\n", "\n", "\n", "class LimitError(Exception):\n", " pass\n", "\n", "\n", "def fix_invalid_email(value: str) -> str:\n", " if not \"@\" in value and \"#\" in value:\n", " return value.replace(\"#\", \"@\")\n", " return value\n", "\n", "@attrs.define\n", "class User:\n", " username: str\n", " email: str = attrs.field(converter=fix_invalid_email)\n", " _password: str = attrs.field(repr=lambda v: \"***\")\n", " _is_vip: bool = attrs.field(default=False, repr=False)\n", " _recent_login_at: datetime = attrs.field(init=False, default=datetime.now())\n", "\n", " @email.validator\n", " def _check_email_suffix(self, attribute, value: str):\n", " if not value.endswith(\"com\"):\n", " raise ValueError(\"invalid domain\")" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "User(username='100gle', email='email@example.com', _password=***, _recent_login_at=datetime.datetime(2022, 11, 19, 10, 44, 49, 229669))" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "User(\"100gle\", email=\"email#example.com\", password=\"password\")" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "# User(\"100gle\", email=\"email@example.net\", password=\"password\") # raise ValueError here!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 导出数据类" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'username': '100gle',\n", " 'email': 'email@example.com',\n", " '_password': 'password',\n", " '_is_vip': False,\n", " '_recent_login_at': datetime.datetime(2022, 11, 19, 10, 44, 49, 229669)}" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "user = User(\"100gle\", email=\"email#example.com\", password=\"password\")\n", "attrs.asdict(user)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'username': '100gle', 'email': 'email@example.com'}" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "attrs.asdict(\n", " user,\n", " filter=lambda attr, value: not attr.name.startswith(\"_\"),\n", ")" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'username': '100gle', 'email': 'email@example.com'}" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from attrs import fields, filters\n", "\n", "attrs.asdict(\n", " user,\n", " filter=filters.include(\n", " fields(User).username,\n", " fields(User).email,\n", " ),\n", ")" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'username': '100gle', 'email': 'email@example.com'}" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "attrs.asdict(\n", " user,\n", " filter=filters.exclude(\n", " fields(User)._password,\n", " fields(User)._is_vip,\n", " datetime,\n", " ),\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3.9.0 ('pandas-startup')", "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.9.0" }, "orig_nbformat": 4, "vscode": { "interpreter": { "hash": "13977d4cc82dee5f9d9535ceb495bd0ab12a43c33c664e5f0d53c24cf634b67f" } } }, "nbformat": 4, "nbformat_minor": 2 }