{ "cells": [ { "cell_type": "markdown", "id": "portuguese-emerald", "metadata": {}, "source": [ "# **Python Decorator**\n", "## **1 가변적 입력값에 가공처리가 필요시 활용**" ] }, { "cell_type": "code", "execution_count": 1, "id": "pediatric-letter", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "get_max(args=(10, 20, 30), kwargs={}) => 30\n", "get_min(args=(), kwargs={'x': 10, 'y': 20, 'z': 30}) => 10\n" ] }, { "data": { "text/plain": [ "10" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def traced(function):\n", " def wrapper(*args, **kwargs):\n", " response = function(*args, **kwargs)\n", " print(f\"{function.__name__}(args={args}, kwargs={kwargs}) => {response}\")\n", " return response\n", " return wrapper\n", "\n", "@traced\n", "def get_max(*args):\n", " return max(args)\n", "\n", "@traced\n", "def get_min(**kwargs):\n", " return min(kwargs.values()) # Value 값을 출력\n", " # return min(kwargs) # Key 값을 출력\n", "\n", "\n", "get_max(10, 20, 30)\n", "get_min(x=10, y=20, z=30)" ] }, { "cell_type": "markdown", "id": "intimate-comparison", "metadata": {}, "source": [ "## **2 매개변수가 있는 데코레이터**" ] }, { "cell_type": "code", "execution_count": 2, "id": "intermediate-anger", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "add_number 의 반환값은 2의 배수 아닙니다.\n" ] }, { "data": { "text/plain": [ "5" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def is_multiple(x):\n", " def real_decorator(function): # 데코레이터 역활 함수\n", " def wrapper(*args, **kwargs): # Wrapper 함수\n", " response = function(*args, **kwargs)\n", " return_text = f\"{function.__name__} 의 반환값은 {x}의 배수\"\n", " if response % x == 0:\n", " print(return_text + \" 입니다.\")\n", " else:\n", " print(return_text + \" 아닙니다.\")\n", " return response\n", " return wrapper\n", " return real_decorator\n", "\n", "\n", "@is_multiple(2)\n", "def add_number(a, b):\n", " return a + b\n", "\n", "add_number(1,4)" ] }, { "cell_type": "markdown", "id": "narrative-project", "metadata": {}, "source": [ "## **3 Class 로 데코레이터 만들기**" ] }, { "cell_type": "code", "execution_count": 3, "id": "convinced-delaware", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "hello_world 함수 시작\n", "hello\n", "hello_world 함수 종료\n" ] } ], "source": [ "class Trace:\n", " def __init__(self, function):\n", " self.function = function\n", " \n", " def __call__(self):\n", " text_string = f\"{self.function.__name__}\"\n", " print(text_string + \" 함수 시작\")\n", " self.function()\n", " print(text_string + \" 함수 종료\")\n", "\n", "@Trace\n", "def hello_world():\n", " print('hello')\n", " \n", "hello_world()" ] }, { "cell_type": "code", "execution_count": 4, "id": "russian-fourth", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "hello_world 함수 시작\n", "hello\n", "hello_world 함수 종료\n" ] }, { "data": { "text/plain": [ "<__main__.Trace at 0x7fcd10d874f0>" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Decorator 를 사용하지 않고서도 동일한 결과값 출력\n", "Trace(hello_world())" ] }, { "cell_type": "code", "execution_count": 5, "id": "automotive-activity", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "add_number (args=(10, 20), kwargs={}) => 30\n", "add_number (args=(), kwargs={'a': 10, 'b': 20}) => 30\n" ] }, { "data": { "text/plain": [ "30" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 매개변수를 활용하는 Class 데코레이터\n", "class Trace:\n", " def __init__(self, function):\n", " self.function = function\n", " \n", " def __call__(self, *args, **kwargs):\n", " response = self.function(*args, **kwargs)\n", " text_string = f\"{self.function.__name__} (args={args}, kwargs={kwargs}) => {response}\"\n", " print(text_string)\n", " return response\n", "\n", "@Trace\n", "def add_number(a, b):\n", " return a + b\n", " \n", "add_number(10, 20)\n", "add_number(a=10, b=20)" ] }, { "cell_type": "markdown", "id": "ready-empire", "metadata": {}, "source": [ "## **3-2 Class 로 매개변수와 반환값 처리 데코레이터 만들기**" ] }, { "cell_type": "code", "execution_count": 12, "id": "hazardous-baseball", "metadata": {}, "outputs": [], "source": [ "class IsMultiple:\n", " def __init__(self, x):\n", " self.x = x\n", " \n", " def __call__(self, function):\n", " def wrapper(a, b):\n", " response = function(a, b)\n", " text = f\"{function.__name__} 의 반환값은 {self.x}의 배수\"\n", " if response % self.x == 0:\n", " print(text + \" 입니다\")\n", " else:\n", " print(text + \"가 아닙니다\")\n", " return response\n", " return wrapper" ] }, { "cell_type": "code", "execution_count": 13, "id": "concrete-powder", "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "__init__() missing 1 required positional argument: 'function'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;34m@\u001b[0m\u001b[0mIsMultiple\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0madd\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mb\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0ma\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mb\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0madd\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mTypeError\u001b[0m: __init__() missing 1 required positional argument: 'function'" ] } ], "source": [ "@IsMultiple(3)\n", "def add(a, b):\n", " return a + b\n", "\n", "add(10,10)" ] }, { "cell_type": "code", "execution_count": 9, "id": "unlike-courage", "metadata": {}, "outputs": [], "source": [ "texts = '삼성전자의 삼성 갤럭시 폴드3는 삼성 전자에서 출시를 하였다'" ] }, { "cell_type": "code", "execution_count": 10, "id": "3023c7d3-f19b-45be-96d8-1f3011ee29cd", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "18" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "texts.find('삼성 전자')" ] }, { "cell_type": "code", "execution_count": 11, "id": "b63b6cbd-dc20-4ee9-b330-6514e2e96c06", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'삼성전자의 삼성 갤럭시 폴드3는 삼성전자에서 출시를 하였다'" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "texts.replace('삼성 전자', '삼성전자')" ] }, { "cell_type": "code", "execution_count": null, "id": "532a5ee0-ea40-43f1-8e76-86bf7fd81fb7", "metadata": {}, "outputs": [], "source": [ "results = {}\n", "results[" ] }, { "cell_type": "code", "execution_count": null, "id": "d569cdb4-014e-4c73-8f54-b2ebb84df1c3", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": 1, "id": "3dd624c0-5a42-404b-b7bb-6e227d812ecc", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Collecting yaspin\n", " Downloading yaspin-2.0.0-py3-none-any.whl (24 kB)\n", "Requirement already satisfied: termcolor<2.0.0,>=1.1.0 in /home/buffet/Coding/Python/Nlpy/lib/python3.8/site-packages (from yaspin) (1.1.0)\n", "Installing collected packages: yaspin\n", "Successfully installed yaspin-2.0.0\n" ] } ], "source": [ "! pip install yaspin" ] }, { "cell_type": "code", "execution_count": 3, "id": "8e612230-e736-4565-903d-1639fc194053", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[K0m \u001b[K" ] } ], "source": [ "# https://github.com/pavdmyt/yaspin\n", "import time\n", "from yaspin import yaspin\n", "\n", "# Context manager:\n", "with yaspin():\n", " time.sleep(3) # time consuming code" ] }, { "cell_type": "code", "execution_count": 4, "id": "f391139a-fd86-45b4-9522-83aca69b6dc4", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[K0m Loading...\u001b[K" ] } ], "source": [ "# Function decorator:\n", "@yaspin(text=\"Loading...\")\n", "def some_operations():\n", " time.sleep(3) # time consuming code\n", "\n", "some_operations()" ] }, { "cell_type": "code", "execution_count": null, "id": "84bd702a-a893-463d-b88a-f8eb7766ea0a", "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.8.5" } }, "nbformat": 4, "nbformat_minor": 5 }