{ "metadata": { "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.6" }, "orig_nbformat": 4, "kernelspec": { "name": "python3", "display_name": "Python 3.8.6 64-bit ('tf': conda)" }, "interpreter": { "hash": "4ea0e157563bacde0b7fd8dc93db6051c9678d5eadbd4117abf1a4cecbc8cd1a" } }, "nbformat": 4, "nbformat_minor": 2, "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "'\\n`Classes` define functions called methods, \\nwhich identify the behaviors and actions \\nthat an object created from the class \\ncan perform with its data.\\n\\n`Instance` is an object that is built \\nfrom a class and contains real data.\\n\\nAttributes created in .__init__() are called `instance attributes`,\\nwhich are spesific only for an instance.\\n\\n`Class attributes` are attributes that have the same value for all class instances. \\nYou can define a class attribute by assigning a value to a variable name outside of .__init__().\\n\\n'" ] }, "metadata": {}, "execution_count": 1 } ], "source": [ "\"\"\"\n", "OOP Basics - Creating class and its instance\n", "\n", "`Classes` define functions called methods, \n", "which identify the behaviors and actions \n", "that an object created from the class \n", "can perform with its data.\n", "\n", "`Instance` is an object that is built \n", "from a class and contains real data.\n", "Instance object consists of attributes and methods.\n", "\n", "Attributes created in .__init__() are called `instance attributes`,\n", "which are spesific only for an instance.\n", "\n", "`Class attributes` are attributes that have the same value for all class instances. \n", "You can define a class attribute by assigning a value to a variable name outside of .__init__().\n", "\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [], "source": [ "class Dog:\n", " species = \"Canis familiaris\"\n", "\n", " def __init__(self, name, age):\n", " self.name = name\n", " self.age = age\n", "\n", " # Another instance method\n", " def speak(self, sound):\n", " return f\"{self.name} says {sound}\"\n", "\n", " # Special instance method - dunder methods\n", " def __str__(self):\n", " return f\"{self.name} is {self.age} years old\"" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [], "source": [ "a = Dog(\"Buddy\", 9)\n", "b = Dog(\"Miles\", 4)" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "False\nFalse\n" ] } ], "source": [ "print(a == b) \n", "print(a is b) " ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Buddy\n9\n" ] } ], "source": [ "print(a.name)\n", "print(a.age)" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "'Canis familiaris'" ] }, "metadata": {}, "execution_count": 34 } ], "source": [ "a.species" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "10" ] }, "metadata": {}, "execution_count": 35 } ], "source": [ "a.age = 10 # We can change values of attributes\n", "a.age" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Felis silvestris\nCanis familiaris\n" ] } ], "source": [ "a.species = 'Felis silvestris'\n", "print(a.species)\n", "print(b.species) # Not changed for another instance" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "'Buddy says Woof woof'" ] }, "metadata": {}, "execution_count": 37 } ], "source": [ "sound = \"Woof woof\"\n", "a.speak(sound)" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "<__main__.Dog at 0x110bc6160>" ] }, "metadata": {}, "execution_count": 38 } ], "source": [ "a" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Buddy is 10 years old\n" ] } ], "source": [ "print(a) # Because we have special instance method __str__" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "\"\"\"Inheritance\n", "- Parent class --> child class\n", "\n", "- Overriding (parent has, child just changes):\n", "You may have inherited your hair color from your mother. It’s an attribute you were born with. Let’s say you decide to color your hair purple. Assuming your mother doesn’t have purple hair, you’ve just ```overridden``` the hair color attribute that you inherited from your mom.\n", "\n", "- Extending (parent do not has):\n", "You also inherit, in a sense, your language from your parents. If your parents speak English, then you’ll also speak English. Now imagine you decide to learn a second language, like German. In this case you’ve ```extended``` your attributes because you’ve added an attribute that your parents don’t have.\n", "\"\"\"\n" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [], "source": [ "class JackRussellTerrier(Dog):\n", " def speak(self, sound=\"Arf\"):\n", " # return f\"{self.name} says {sound}\"\n", " return super().speak(sound)\n", "\n", "class Dachshund(Dog):\n", " def speak(self, sound=\"Yap\"):\n", " return f\"{self.name} says {sound}\"\n", "\n", "class Bulldog(Dog):\n", " def speak(self, sound=\"Woof\"):\n", " return f\"{self.name} says {sound}\"" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Miles\n4\nMiles is 4 years old\nMiles says Arf\nMiles says Bla bla bla\n" ] } ], "source": [ "c = JackRussellTerrier(\"Miles\", 4)\n", "print(c.name)\n", "print(c.age)\n", "print(c)\n", "print(c.speak()) # Great, now we can use .speak() even without passing arg\n", "print(c.speak(\"Bla bla bla\"))" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "True\nTrue\nFalse\n" ] } ], "source": [ "print(isinstance(c, Dog))\n", "print(isinstance(c, JackRussellTerrier))\n", "print(isinstance(c, Bulldog))" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Bird is ready\nPenguin is ready\nPenguin\nSwim faster\nRun faster\n" ] } ], "source": [ "# One more example\n", "# parent class\n", "class Bird:\n", " \n", " def __init__(self):\n", " print(\"Bird is ready\")\n", "\n", " def whoisThis(self):\n", " print(\"Bird\")\n", "\n", " def swim(self):\n", " print(\"Swim faster\")\n", "\n", "# child class\n", "class Penguin(Bird):\n", "\n", " def __init__(self):\n", " # call super() function\n", " super().__init__()\n", " print(\"Penguin is ready\")\n", "\n", " def whoisThis(self):\n", " print(\"Penguin\")\n", "\n", " def run(self):\n", " print(\"Run faster\")\n", "\n", "peggy = Penguin()\n", "peggy.whoisThis()\n", "peggy.swim()\n", "peggy.run()" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Selling Price: 900\nSelling Price: 900\nSelling Price: 1000\n" ] } ], "source": [ "\"\"\"\n", "Encapsulation\n", "\n", "We can restrict access to methods and variables. This prevents data from direct modification which is called encapsulation. In Python, we denote private attributes using underscore as the prefix i.e single _ or double __\n", "\n", "\"\"\"\n", "class Computer:\n", "\n", " def __init__(self):\n", " self.__maxprice = 900\n", "\n", " def sell(self):\n", " print(\"Selling Price: {}\".format(self.__maxprice))\n", "\n", " def setMaxPrice(self, price):\n", " self.__maxprice = price\n", "\n", "c = Computer()\n", "c.sell()\n", "\n", "# change the price\n", "c.__maxprice = 1000\n", "c.sell()\n", "\n", "# using setter function\n", "c.setMaxPrice(1000)\n", "c.sell()" ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Parrot can fly\nPenguin can't fly\n" ] } ], "source": [ "\"\"\"\n", "Polymorphism\n", "\n", "Polymorphism is an ability (in OOP) to use a common interface for multiple forms (data types).\n", "\n", "Suppose, we need to color a shape, there are multiple shape options (rectangle, square, circle). However we could use the same method to color any shape. This concept is called Polymorphism.\n", "\n", "\"\"\"\n", "class Parrot:\n", " def fly(self):\n", " print(\"Parrot can fly\")\n", " \n", " def swim(self):\n", " print(\"Parrot can't swim\")\n", "\n", "class Penguin:\n", " def fly(self):\n", " print(\"Penguin can't fly\")\n", " \n", " def swim(self):\n", " print(\"Penguin can swim\")\n", "\n", "# common interface\n", "def flying_test(bird):\n", " bird.fly()\n", "\n", "#instantiate objects\n", "blu = Parrot()\n", "peggy = Penguin()\n", "\n", "# passing the object\n", "flying_test(blu)\n", "flying_test(peggy)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ] }