{ "cells": [ { "cell_type": "markdown", "id": "02d718a7-f3a0-41cc-a3fd-1aa6a9907ec4", "metadata": {}, "source": [ "# **Python Book1**\n", "**[효율적 개발로 이끄는 파이썬 실천기술 Jupyter Notebook](https://nbviewer.org/github/Jpub/fulfillPython/tree/main/)**\n", "\n", "\n", "" ] }, { "cell_type": "markdown", "id": "1240cacf-71f9-4157-a6d2-3fd9d1811c79", "metadata": {}, "source": [ "## **Chapter 4 데이터 구조**\n", "### 01 **dict()**" ] }, { "cell_type": "code", "execution_count": 1, "id": "17972d68-b9e2-46b3-bce9-6b00fc4ea8ef", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'note': 1, 'notebook': 2, 'sketchbook': 3}" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dict(note=1, notebook=2, sketchbook=3)" ] }, { "cell_type": "code", "execution_count": 2, "id": "8500e2ae-0b11-4732-8943-052e81ef9ac8", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "items = {'note':1, 'notebook':2, 'sketchbook':3 }\n", "items['book'] = 4\n", "del items['note'] # dict() 객체에서 제외 : 별로 출력은 없음\n", "items.pop('notebook') # dict() 객체에서 제외 : 해당 value 를 출력" ] }, { "cell_type": "code", "execution_count": 3, "id": "046ad296-e0c9-4908-8884-77498edd9211", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'sketchbook': 3, 'book': 4}\n" ] }, { "data": { "text/plain": [ "'None Existed'" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "print(items)\n", "items.get('note', \"None Existed\") # .get() : key의 값을 호출, 없으면 뒤의 값 출력" ] }, { "cell_type": "code", "execution_count": 4, "id": "a1ef9936-7124-451a-9cfa-aa2388fb0fc4", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'sketchbook': 3, 'book': 4, 'notes': 10}" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# .update(dict()) : dict() 객체 합치는 메서드 \n", "items_two = {'notes':10}\n", "items.update(items_two)\n", "items" ] }, { "cell_type": "code", "execution_count": 5, "id": "2dafa40e-8f38-4383-a4f3-c5a88c6869ce", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "'book' in items" ] }, { "cell_type": "code", "execution_count": 6, "id": "4aeac426-9ae6-4a02-bd9d-53736e972aee", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "'note' not in items" ] }, { "cell_type": "markdown", "id": "07a0aff4-e04b-4166-ba10-0f11a2c8c51b", "metadata": {}, "source": [ "### 02 **set()**" ] }, { "cell_type": "code", "execution_count": 7, "id": "0b5b24be-196d-418a-aa17-c282773734c8", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'book', 'note', 'notebook', 'sketchbook'}" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "items = {'note', 'notebook', 'sketchbook'}\n", "items.add('book')\n", "items" ] }, { "cell_type": "code", "execution_count": 8, "id": "70106686-5506-46fe-b6e9-52e665619cad", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'sketchbook'" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "items.pop() # 순서와 Key 가 별도로 없음" ] }, { "cell_type": "code", "execution_count": 9, "id": "d365d1f1-f0ab-4824-bf16-af9b4de806db", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'book', 'note', 'notebook'}" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "items" ] }, { "cell_type": "markdown", "id": "acd7fcd6-61c0-449a-b45d-608141b59582", "metadata": {}, "source": [ "### 03 **user Function()**" ] }, { "cell_type": "code", "execution_count": 10, "id": "fb4bbc9d-42f5-41b6-b1f4-55a490aaec1a", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def increment(page_number, last):\n", " r\"\"\"page_number + 1 값이 last 값을 넘어가는지 확인\"\"\"\n", " next_page = page_number + 1\n", " if next_page <= last:\n", " return next_page\n", " raise ValueError('Invalid arguments')\n", "\n", "increment(2, 10)" ] }, { "cell_type": "markdown", "id": "e5be43d3-3f9d-42c8-ad11-7fdbaae83820", "metadata": {}, "source": [ "### 04 **lambda()**\n", "이름이 없는 함수" ] }, { "cell_type": "code", "execution_count": 11, "id": "dd34d707-b497-41e2-9b8b-235c3be75236", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " at 0x7f2f087f64c0>\n" ] }, { "data": { "text/plain": [ "4" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "increment = lambda num: num+1\n", "print(increment)\n", "increment(3)" ] }, { "cell_type": "code", "execution_count": 12, "id": "f3a51be0-70a0-49d5-b205-7fb5cc37cb4f", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['one', 'two']" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "nums = ['one', 'two', 'three']\n", "filtered = filter(lambda x : len(x) == 3, nums)\n", "list(filtered)" ] }, { "cell_type": "code", "execution_count": 13, "id": "1194a5ec-6d43-4219-8ef1-e503222271c2", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n", "True\n", "False\n" ] }, { "data": { "text/plain": [ "['ok', None, None]" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Check if given numbers are in range using lambda function\n", "test = lambda x : True if (x > 10 and x < 20) else False\n", "print(test(3))\n", "print(test(12))\n", "print(test(24))\n", "\n", "# https://thispointer.com/python-how-to-use-if-else-elif-in-lambda-functions/\n", "# https://stackoverflow.com/questions/60261960/how-to-use-lambda-if-else-in-map-on-list-in-python\n", "list(map(lambda x : 'ok' if x == \"apple\" else None, ['apple', 'banana', 'cherry']))" ] }, { "cell_type": "markdown", "id": "ab543a25-d48d-4eac-aa53-996529c1f861", "metadata": {}, "source": [ "### 05 **타입 힌트**" ] }, { "cell_type": "code", "execution_count": 14, "id": "116e6dea-d169-4b1a-8695-20544691695f", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'page_num': int,\n", " 'last': int,\n", " 'ignore_error': bool,\n", " 'return': typing.Union[int, NoneType]}" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# (p127) Optional : None 의 가능성이 있을 때 사용한다 \n", "from typing import Optional\n", "def incerment(\n", " page_num: int,\n", " last: int, *,\n", " ignore_error: bool = False) -> Optional[int]:\n", " \n", " next_page = page_num + 1\n", " if next_page <= last:\n", " return next_page\n", " if ignore_error:\n", " return None\n", " raise ValueError('Invalid arguments')\n", "\n", "incerment.__annotations__\n", "# increment(1, 3, ignore_error=1)" ] }, { "cell_type": "code", "execution_count": 15, "id": "9284872b-a2d4-428e-ac1e-f85c24048f32", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def decrement(page_number:int) -> int:\n", " previous_page: int\n", " previous_page = page_number - 1\n", " return previous_page\n", "\n", "decrement(2)" ] }, { "cell_type": "code", "execution_count": 16, "id": "85e2f612-192a-4127-a646-8a464860e31b", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def increment(\n", " page_number: int,\n", " last:int,\n", " *,\n", " ignore_error: bool = False) -> Optional[int]:\n", " \n", " next_page = page_number + 1\n", " if next_page <= last:\n", " return next_page\n", " if ignore_error:\n", " return None\n", " raise ValueError(\"Invalid arguments\")\n", "\n", "increment(1, 10, ignore_error=1)" ] }, { "cell_type": "markdown", "id": "c2e35b7d-05be-42ad-a24f-82b27322be63", "metadata": {}, "source": [ "## **Chapter 6-1 클래스와 인스턴스**\n", "**[Jupyter Notebook](https://nbviewer.org/github/Jpub/fulfillPython/blob/main/06-classes/interactive.ipynb)**" ] }, { "cell_type": "code", "execution_count": 17, "id": "481d269e-a242-442f-9aee-015ce1abf905", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "__main__.Page" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 클래스 객체 만들기\n", "class Page:\n", " def __init__(self, number, content):\n", " self.number = number\n", " self.content = content\n", " \n", " def output(self):\n", " return f'{self.content}'\n", "Page" ] }, { "cell_type": "code", "execution_count": 18, "id": "5181e78e-02b9-4873-a952-932ad7a597a9", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "__main__.Page" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 클래스 인스턴스 만들기\n", "title_page = Page(0, 'Python Practice Book')\n", "type(title_page)" ] }, { "cell_type": "code", "execution_count": 19, "id": "2a5cb65a-caeb-4461-acda-bc032a19fd47", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 클래스 객체의 인스턴스 동일성 확인\n", "isinstance(title_page, Page)" ] }, { "cell_type": "code", "execution_count": 20, "id": "ffd21f88-1fe3-41e8-abbb-a75dfff12ebf", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'__class__ , __delattr__ , __dict__ , __dir__ , __doc__ , __eq__ , __format__ , __ge__ , __getattribute__ , __gt__ , __hash__ , __init__ , __init_subclass__ , __le__ , __lt__ , __module__ , __ne__ , __new__ , __reduce__ , __reduce_ex__ , __repr__ , __setattr__ , __sizeof__ , __str__ , __subclasshook__ , __weakref__ , content , number , output'" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\" , \".join(dir(title_page))" ] }, { "cell_type": "code", "execution_count": 21, "id": "642024b3-bb00-4e28-ac44-23129bfc7463", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Python Practice Book'" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "title_page.output()" ] }, { "cell_type": "markdown", "id": "629776f7-bc23-4c90-8650-c3e8fcf820af", "metadata": {}, "source": [ "## **Chapter 6-2 Class Method**\n", "- `__NEW__` 의 `cls` : **(p 138)**\n", " - 주 용도는 **입력 파라미터값을 인스턴스 생성시** 연산\n", " - `cls` 를 **클래스 메서드(Class Method)** 라고 한다 \n", "- `__INIT__` : 이니셜라이저 는 인스턴스\n", " - `__new__` 출력값은 `__init__` 의 첫번째 인수 `self` 로 전달 받는다" ] }, { "cell_type": "code", "execution_count": 22, "id": "2e70bcb9-7836-4887-8b0c-a5595d11d0a1", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "cls=\n", "new (1, 2, 3)\n", "init (1, 2, 3)\n" ] } ], "source": [ "class Klass:\n", " # new 의 첫번째 인수 : 클래스의 Method\n", " # @classmethod 대신 __new__ 를 적용\n", " def __new__(cls, *args):\n", " r\"\"\"cls : 클래스\"\"\"\n", " print(f\"{cls=}\")\n", " print('new', args)\n", " data = args\n", " return super().__new__(cls)\n", " \n", " def __init__(self, *args):\n", " print('init', args)\n", "\n", "# 인스턴스화\n", "kls = Klass(1,2,3)" ] }, { "cell_type": "code", "execution_count": 23, "id": "4aa552b0-7f70-47bc-840c-2ca3e71fbd2a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Creating Instance\n", "2 3\n", "Creating Instance\n", "1 2\n" ] } ], "source": [ "# Class 파라미터 __init__ 전달 (`__new__` -> `__init__`) \n", "# Class parametor => `cls` 로 __new__ => `self` 로 __init__ 전달\n", "# 1) Key 를 지정 안한 경우 : 순차적 Key 값을 적용\n", "# 2) Key 를 지정한 경우 : Key 에 맞게 대입된다\n", "class Craft:\n", " def __new__(cls, *args, **kwargs):\n", " print (\"Creating Instance\")\n", " return super().__new__(cls) # instance\n", "\n", " def __init__(self, a, b):\n", " self.a = a\n", " self.b = b\n", "\n", "i = Craft(2, 3)\n", "print(i.a, i.b)\n", "\n", "i = Craft(a=1, b=2)\n", "print(i.a, i.b)" ] }, { "cell_type": "code", "execution_count": 24, "id": "71480c29-da72-4e0d-9ef4-fd6a9692e1b2", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# __new__() 사용시 주의할 점\n", "# :: 인스턴스 생성시 값을 출력한다 \n", "class Evil:\n", " def __new__(cls, *args):\n", " return 1\n", "\n", "evil = Evil()\n", "isinstance(evil, Evil)" ] }, { "cell_type": "markdown", "id": "1eb16710-1444-4d4f-ad62-e584102dfca0", "metadata": {}, "source": [ "## **Chapter 6-3 프로퍼티 1 (getter, setter)**\n", "> **다른 변수의 값** 을 **Class 인스턴스** 에서 활용하는 용도로 사용한다 ([Setter 와 Getter 개념의 이해](https://jinmay.github.io/2019/11/23/python/python-class-first/))\n", "- **getter** 메소드 : **값을 얻어올 때** 사용하는 기능으로 **@property** 를 사용\n", "- **setter** 메소드 : **읽은 값** 을 **쓰는** 기능으로 **@변수.setter** 를 사용" ] }, { "cell_type": "code", "execution_count": 25, "id": "2f80d7bd-cbb4-48cc-947a-40daa3991a54", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(2000, 0)" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "class Book:\n", "\n", " def __init__(self, raw_price):\n", " if raw_price < 0:\n", " raise ValueError('price must be positive')\n", " self.raw_price = raw_price\n", " self._discount_value = 0 # 초깃값\n", "\n", " @property\n", " def discount(self):\n", " return self._discount_value\n", " \n", " @discount.setter\n", " def discount(self, value):\n", " if value < 0 or 100 < value:\n", " raise ValueError(\n", " 'discounts must be between 0 and 100')\n", " self._discount_value = value\n", " \n", " @property\n", " def price(self):\n", " multiple = 100 - self._discount_value\n", " return int(self.raw_price * multiple / 100)\n", "\n", "book = Book(2000)\n", "book.price, book.discount" ] }, { "cell_type": "code", "execution_count": 26, "id": "e233cebf-f8e6-4720-af18-fcde7a581b79", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1600" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "book.discount = 20\n", "book.price" ] }, { "cell_type": "markdown", "id": "d13650c1-70c6-41d1-bc00-0b24395565dc", "metadata": {}, "source": [ "## **Chapter 6-3 프로퍼티 2 (히든 속성)**\n", "> 변수이름 앞 **`_`** 는 **외부에 공개할 필요 없는** 프라이빗 변수이나, **약속에 불과** 해서 외부서 참조가능\n", "\n", "> **하지만**, 변수이름 앞 **`__`** 두개는 **클래스 이름을 덧붙인 변수** 즉 `_클래스명__변수명` 으로 자동 변환된다" ] }, { "cell_type": "code", "execution_count": 27, "id": "280b5700-8af3-4fc2-a564-7d820e8b424a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[31m'Klass' object has no attribute '__x'\u001b[0m\n" ] }, { "data": { "text/plain": [ "10" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "class Klass:\n", " def __init__(self, x):\n", " self.__x = x\n", "\n", "\n", "kls = Klass(10)\n", "try:\n", " kls.__x\n", "except Exception as e:\n", " import termcolor # termcolor.COLORS\n", " print(termcolor.colored(e, 'red'))\n", "\n", "kls._Klass__x" ] }, { "cell_type": "markdown", "id": "f978e11f-34b7-4eef-8050-250888e009cd", "metadata": { "tags": [] }, "source": [ "## **Chapter 6-4 [클래스 메서드](https://nirsa.tistory.com/113)** [개념 익히기]\n", "- **정적 메소드 (@staticmethod)** 는 **부모 의 원본 값** 을 호출한다\n", "- **클래스 메소드 (classmethod)** 는 **자식에서 변경된 값** 을 호출한다\n", "- **자식객체** 에서 **부모객체의 값 getter** 와 **setter**\n", "- 때문에 **부모 클래스의 인스턴스** 에서는 **동일** 하게 보입니다." ] }, { "cell_type": "code", "execution_count": 28, "id": "4c3122db-d551-44a0-b630-8b21e0acb2c0", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "8\n", "0\n", "16\n" ] } ], "source": [ "# 부모 클래스의 인스턴스 에서는 동일하게 보인다..\n", "class test:\n", " def instance_add(self, a, b): \n", " return a + b \n", " \n", " @staticmethod # 정적 메서드는 self 불필요\n", " def static_add(a, b):\n", " return a - b\n", " \n", " @classmethod # 클래스 메서드는 cls 를 첫번째 인자로 사용\n", " def class_add(cls, a, b):\n", " return a * b\n", "\n", "a = test \n", "print(a.instance_add(None, 4, 4)) # 원본 함수의 내용 \n", "print(test.static_add(4, 4)) # 정적메서드 내용 \n", "print(test.class_add(4, 4)) # 클래스메서드 내용" ] }, { "cell_type": "code", "execution_count": 29, "id": "42528cf0-21dc-427d-bb4f-7c1bb59dc8f6", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "OS: window10\n", "OS: Linux\n" ] } ], "source": [ "## 하지만 이를 상속한 자식 클래스에서는 차이가 발생한다\n", "# 클래스 메소드 : cls로 `현재 자기가 실행된 클래스 속성` 을 가져온다\n", "# 정적 메소드 : 부모 클래스(Windows)의 속성을 가져온다\n", "class Windows:\n", " os = \"window10\" # 클래스 속성 \n", " \n", " def __init__(self):\n", " self.out = \"OS: \" + self.os \n", "\n", " def os_output(self):\n", " print(self.out) \n", "\n", " @staticmethod # 부모원본\n", " def static_os():\n", " return Windows() \n", " \n", " @classmethod # 자식의 변경내용\n", " def class_os(cls):\n", " return cls() \n", " \n", "class Linux(Windows): \n", " os = \"Linux\" # 클래스 속성 \n", "\n", "Linux.static_os().os_output() # 부모의 원본을 호출\n", "Linux.class_os().os_output() # 자식의 변경된 내용을 호출" ] }, { "cell_type": "markdown", "id": "17e9f1e8-b2fc-43e3-b6e3-223d5d889f7c", "metadata": { "tags": [] }, "source": [ "## **Chapter 6-4 클래스 메서드 2 (`@classmethod`)**\n", "**@classmethod** 클래스에 속한 메서드로, 첫번째 인수에 클래스 객체를 전달 합니다\n", "- **@classmethod** 를 붙이는 것을 제외하면, 다른 메서드와 동일\n", "- 첫 번째 인수가 클래스 객체로 self 가 아닌, `cls` 이름을 사용" ] }, { "cell_type": "code", "execution_count": 30, "id": "03bb04ff-e336-47b1-94ca-1146cf430f7d", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "<__main__.Page at 0x7f2f08797e80>" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from operator import attrgetter\n", "\n", "class Page:\n", " book_title = 'Python Practice Book :: ======'\n", " \n", " def __init__(self, number, content):\n", " self.number = number\n", " self.content = content\n", " \n", " def output(self):\n", " return f'{self.content}'\n", " \n", " @classmethod\n", " def print_pages(cls, *pages):\n", " print(cls.book_title)\n", " pages = list(pages)\n", " \n", " # key=attrgetter('number') : sorted() 함수의 정렬기준\n", " for page in sorted(pages, key=attrgetter('number')):\n", " print(page.output())\n", "\n", "first = Page(1, 'first page')\n", "second = Page(20, 'second book page')\n", "third = Page(3, 'third page')\n", "first" ] }, { "cell_type": "code", "execution_count": 31, "id": "3665dc1c-80e7-42ee-8828-63f561d5ccb4", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Python Practice Book :: ======\n", "first page\n", "third page\n", "second book page\n" ] } ], "source": [ "# 클래스를 활용한 호출\n", "Page.print_pages(first, second, third)" ] }, { "cell_type": "code", "execution_count": 32, "id": "7fc2901a-bb42-485b-a1fa-0a80e75ac0bc", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Python Practice Book :: ======\n", "first page\n", "third page\n", "second book page\n" ] } ], "source": [ "# 인스턴스 객체를 활용한 호출\n", "first.print_pages(first, second, third)" ] }, { "cell_type": "code", "execution_count": 33, "id": "c1e0b6e0-d364-42b4-86e7-e6502dbc0a6b", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "<__main__.Page at 0x7f2f087aa3d0>" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from operator import attrgetter\n", "\n", "class Page:\n", " book_title = 'Python Practice Book :: ======'\n", " \n", " def __init__(self, number, content):\n", " self.number = number\n", " self.content = content\n", " \n", " def output(self):\n", " return f'{self.content}'\n", " \n", " @classmethod\n", " def print_pages(cls, *pages):\n", " print(cls.book_title)\n", " pages = list(pages)\n", " \n", " # key=attrgetter('number') : sorted() 함수의 정렬기준\n", " for page in sorted(pages, key=attrgetter('number')):\n", " print(page.output())\n", "\n", "first = Page(1, 'first page')\n", "second = Page(20, 'second book page')\n", "third = Page(3, 'third page')\n", "first" ] }, { "cell_type": "code", "execution_count": 34, "id": "0d5c5b17-6f4c-4f2a-87d5-b99caf45b91d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Python Practice Book :: ======\n", "first page\n", "third page\n", "second book page\n" ] } ], "source": [ "# 클래스를 활용한 호출\n", "Page.print_pages(first, second, third)" ] }, { "cell_type": "code", "execution_count": 35, "id": "da365847-a654-41c3-8920-fdb89c232efd", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Python Practice Book :: ======\n", "first page\n", "third page\n", "second book page\n" ] } ], "source": [ "# 인스턴스 객체를 활용한 호출\n", "first.print_pages(first, second, third)" ] }, { "cell_type": "code", "execution_count": 36, "id": "2ce33f16-0cc0-4f29-8e17-12009ce81b11", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'first page'" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "first.content" ] }, { "cell_type": "markdown", "id": "29741762-7077-4352-997c-0fbe11878fcc", "metadata": {}, "source": [ "## **Chapter 6-5 클래스 메서드 3 (`@staticmethod`)**\n", "- 위의 클래스 메서드와 거의 같은 구문이다\n", "- 인스턴스 및 클래스 객체로는 전달되지 않고, 호출시에만 전달값을 출력한다" ] }, { "cell_type": "code", "execution_count": 37, "id": "c91f501c-9dfc-42bd-a231-0a4ab40bc5e9", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "class Page:\n", " def __init__(self, number, content):\n", " self.number = number\n", " self.content = content\n", " \n", " @staticmethod\n", " def check_blank(page):\n", " return bool(page.content)\n", "\n", "page = Page(1, '')\n", "Page.check_blank(page)" ] }, { "cell_type": "markdown", "id": "633b326b-331b-4f3a-8e72-dde93a0d3557", "metadata": {}, "source": [ "## **Chapter 6-6 클래스의 상속**\n", "`class Inheritance`\n", "- `Child Class` 에서 `Base Class` 가 갖는 Method 를 그래도 사용하면서 변수등을 추가한다\n", "- `__str__` 와 같은 내장 타입은 사용자 클래스도 동일하게 서브 클래스로 정의된다" ] }, { "cell_type": "code", "execution_count": 38, "id": "f9662c0b-6863-4749-90b3-7740f10f56fa", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "PYTHON PRACTICE BOOK\n" ] }, { "data": { "text/plain": [ "(0, 'Python Practice Book')" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "class Page:\n", " def __init__(self, number, content):\n", " self.number = number\n", " self.content = content\n", " \n", " def output(self):\n", " return f'{self.content}'\n", "\n", "# Method Override : Page 클래스를 통으로 상속\n", "class TitlePage(Page):\n", " def output(self):\n", " title = super().output()\n", " return title.upper()\n", "\n", "title = TitlePage(0, 'Python Practice Book')\n", "print(title.output())\n", "title.number, title.content" ] }, { "cell_type": "code", "execution_count": 39, "id": "f8578f9b-1d61-49d4-b6d6-d6f27939fb5c", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('16.0 cm', '16.0 inch')" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "class Length(float):\n", " def to_cm(self):\n", " return super().__str__() + ' cm'\n", "\n", " def to_inch(self):\n", " return super().__str__() + ' inch'\n", " \n", "pencil_length = Length(16)\n", "pencil_length.to_cm(), pencil_length.to_inch()" ] }, { "cell_type": "markdown", "id": "c8284e31-af29-47c8-87a7-90f91d003e77", "metadata": {}, "source": [ "## **Chapter 6-7 다중상속**\n", "`Multiple Inheritance`\n", "- **완결성이 있는 원본 클래스(Base Class)** 에, **추가 클래스로 메서드를 추가하는** 용도\n", "- 추가 클래스의 `self` 는 **원본 클래스의 요소와 메서드** 를 연결해야, 자식클래스가 잘 작동한다\n", "- Base Class 에서 `,` 로 여러개를 구분한다" ] }, { "cell_type": "code", "execution_count": 40, "id": "547d8a18-7dba-4009-8fcf-a4dd8f938abf", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'web content'" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 부모 클래스1\n", "class Page:\n", " def __init__(self, number, content):\n", " self.number = number\n", " self.content = content\n", "\n", " def output(self):\n", " return f'{self.content}'\n", "\n", "# 부모 클래스\n", "class HTMLPageMixin:\n", " def to_html(self):\n", " return f'{self.output()}'\n", " \n", "class WebPage(Page, HTMLPageMixin):\n", " pass\n", "\n", "page = WebPage(0, 'web content')\n", "page.to_html()" ] }, { "cell_type": "markdown", "id": "15b41022-082a-4e8a-9cee-de6076e0933d", "metadata": {}, "source": [ "## **Chapter 7 모듈, 패키지, 스코프**\n", "### 01 **클로저 `nonlocal`**\n", "외부에 있는 변수를 참조한다" ] }, { "cell_type": "code", "execution_count": 41, "id": "5d168b67-3d1e-49bb-a275-e4bb24dd7dfc", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(._increase()>, 1, 2)" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def counter():\n", " count = 0\n", " \n", " def _increase():\n", " nonlocal count\n", " count += 1\n", " return count\n", " return _increase\n", "\n", "counter1 = counter()\n", "counter1, counter1(), counter1()" ] } ], "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.10" } }, "nbformat": 4, "nbformat_minor": 5 }