{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "
\n",
    "\n",
    "\n",
    "\n",
    "
\n", "\n", "# Object Oriented Programming (II)\n", "
\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "
\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Classes have a bunch of special methods ###\n", "the mirror of `__init__` is `__del__`\n", "(it is the tear down during clean up)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class Bear:\n", " def __init__(self,name):\n", " self.name = name\n", " print(\" made a bear called %s\" % (name))\n", " def __del__(self):\n", " print(\"Bang! %s is no longer.\" % self.name)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "y = Bear(\"Yogi\") ; c = Bear(\"Cal\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "del y; del c" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "## note that I'm assigning y twice here\n", "y = Bear(\"Yogi\") ; y = Bear(\"Cal\") " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we quit (not from the notebook but the interpreter or ipython)\n", "\n", "```python\n", " >>> f = Bear(\"Fuzzy\")\n", " ` made a bear called Fuzzy`\n", " >>> exit()\n", " `Bang! Fuzzy is no longer.`\n", " BootCamp>\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "neither `__init__` or `__del__` are allowed to return anything\n", "
" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%%file bear.py\n", "import datetime\n", "class Bear:\n", " logfile_name = \"bear.log\"\n", " bear_num = 0\n", " all_bear_names = []\n", " def __init__(self,name):\n", " self.name = name\n", " print((\" made a bear called %s\" % (name)))\n", " self.logf = open(Bear.logfile_name,\"a\")\n", " Bear.bear_num += 1\n", " self.my_num = Bear.bear_num\n", " self.logf.write(\"[%s] created bear #%i named %s\\n\" % \\\n", " (datetime.datetime.now(),Bear.bear_num,self.name))\n", " self.logf.flush()\n", " \n", " def growl(self,nbeep=5):\n", " print((\"\\a\"*nbeep))\n", "\n", " def __del__(self):\n", " print((\"Bang! %s is no longer.\" % self.name))\n", " self.logf.write(\"[%s] deleted bear #%i named %s\\n\" % \\\n", " (datetime.datetime.now(),self.my_num,self.name))\n", " self.logf.flush()\n", " # decrement the number of bears in the population\n", " Bear.bear_num -= 1\n", " # dont really need to close because Python will do the garbage collection\n", " # for us. but it cannot hurt to be graceful here.\n", " self.logf.close()\n", "\n", " def __str__(self):\n", " return \" name = %s bear number = %i (population %i)\" % \\\n", " (self.name, self.my_num,Bear.bear_num)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "!rm bear.log\n", "%run bear" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "a = Bear(\"Yogi\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "b = Bear(\"Yogi\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "b = a" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "b = Bear(\"Fuzzy\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "Bear.bear_num " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "del a; del b" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "Bear.bear_num" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "!cat bear.log" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Classes have a bunch of special methods ###\n", "\n", "`__str__` is a method that defines how a Class should represent itself as a string\n", "\n", "it takes only self as an arg, must return a string" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "run bear" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "b = Bear(\"Fuzzy\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(b)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "a = Bear(\"Yogi\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "this is the kind of formatting that datetime() is doing in it's own `__str__`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%%file bear2.py\n", "import datetime\n", "class Bear:\n", " logfile_name = \"bear.log\"\n", " bear_num = 0\n", " def __init__(self,name):\n", " self.name = name\n", " print(\" made a bear called %s\" % (name))\n", " self.logf = open(Bear.logfile_name,\"a\")\n", " Bear.bear_num += 1\n", " self.created = datetime.datetime.now()\n", " self.my_num = Bear.bear_num\n", " self.logf.write(\"[%s] created bear #%i named %s\\n\" % \\\n", " (datetime.datetime.now(),Bear.bear_num,self.name))\n", " self.logf.flush()\n", " \n", " def growl(self,nbeep=5):\n", " print(\"\\a\"*nbeep)\n", "\n", " def __del__(self):\n", " print(\"Bang! %s is no longer.\" % self.name)\n", " self.logf.write(\"[%s] deleted bear #%i named %s\\n\" % \\\n", " (datetime.datetime.now(),self.my_num,self.name))\n", " self.logf.flush()\n", " # decrement the number of bears in the population\n", " Bear.bear_num -= 1\n", " # dont really need to close because Python will do the garbage collection\n", " # for us. but it cannot hurt to be graceful here.\n", " self.logf.close()\n", "\n", " def __str__(self):\n", " age = datetime.datetime.now() - self.created\n", " return \" name = %s bear (age %s) number = %i (population %i)\" % \\\n", " (self.name, age, self.my_num,Bear.bear_num)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# add some dynamic aging to the bears\n", "from bear2 import Bear as Bear2" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "a = Bear2(\"Yogi\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(a)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Emulating Numeric operations ###\n", "you can define a whole bunch of ways that instances behave upon numerical operation\n", "\n", "(e.g., `__add__` is what gets called when you type instance_1 + instance_2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n",
    "\n",
    "__add__(self, other)\n",
    "\n",
    "__sub__(self, other)\n",
    "\n",
    "__mul__(self, other)\n",
    "\n",
    "__div__(self, other)\n",
    "\n",
    "__mod__(self, other)\n",
    "\n",
    "__divmod__(self, other)\n",
    "\n",
    "__pow__(self, other[, modulo])\n",
    "\n",
    "__lshift__(self, other)\n",
    "\n",
    "__rshift__(self, other)\n",
    "\n",
    "__and__(self, other)\n",
    "\n",
    "__xor__(self, other)\n",
    "\n",
    "
" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%%file bear1.py\n", "\n", "class Bear:\n", " \"\"\"\n", " class to show off addition (and multiplication)\n", " \"\"\"\n", " bear_num = 0\n", " def __init__(self,name):\n", " self.name = name\n", " print(\" made a bear called %s\" % (name))\n", " Bear.bear_num += 1\n", " self.my_num = Bear.bear_num\n", "\n", " def __add__(self,other):\n", " ## spawn a little tike\n", " cub = Bear(\"progeny_of_%s_and_%s\" % (self.name,other.name))\n", " cub.parents = (self,other)\n", " return cub\n", "\n", " def __mul__(self,other):\n", " ## multiply (as in \"go forth and multiply\") is really the same as adding\n", " return self.__add__(other)\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from bear1 import Bear as Bear1" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "y = Bear1(\"Yogi\") ; c = Bear1(\"Fuzzy\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "our_kid = y + c" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "our_kid." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "our_kid.parents" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "our_kid.parents[0].name" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "our_kid.parents[1].name" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "y.broken_limb = True" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "our_kid1 = y * c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Other Useful Specials ###" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n",
    "__dict__ : Dictionary containing the class's namespace.\n",
    "__doc__ : Class documentation string, or None if undefined. \n",
    "__name__: Class name. \n",
    "__module__: Module name in which the class is defined. This attribute is \"__main__\" in interactive mode. \n",
    "__bases__ : A possibly empty tuple containing the base classes, in the order of their occurrence in the base class list. \n",
    "
" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(Bear1.__doc__)\n", "print(Bear1.__name__)\n", "print(Bear1.__module__)\n", "print(Bear1.__bases__)\n", "print(Bear1.__dict__)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## \"Hiding\" class data attributes" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "class JustCounter:\n", " __secretCount = 0\n", " x = 0\n", " def count(self):\n", " self.__secretCount += 1\n", " self.x += 1\n", " print(self.__secretCount)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "counter = JustCounter()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "counter.count() ; counter.count() " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(counter.x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(counter.__secretCount)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "no attribute is ever precisely private \n", "\n", "double underscore attributes are exposed as `object._className__attrName`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "counter._JustCounter__secretCount" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### A note on referencing... ###" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "a = Bear(\"Yogi\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "a" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "b = a" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "b" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "a.name = \"Fuzzy\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "b.name" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "Bear.bear_num" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import copy" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "c = copy.copy(a)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "c # new memory location" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "Bear.bear_num" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "c.name" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "c.name = \"Smelly\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "a.name" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "a.mylist = [1,2,3]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "b.mylist" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "c.mylist" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "d = copy.copy(a)\n", "d.mylist" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "d.name" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "d.name = \"Yogi\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "a.name" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "a.mylist[0] = -1" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "d.mylist" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "e = copy.deepcopy(a)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "a.__dict__" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "del a.logf" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "e = copy.deepcopy(a)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "a.mylist[0] = \"a\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "e.mylist" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "Bear.bear_num" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`deepcopy`: copies all attributes pointed to internally" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Subclassing & Inheritance\n", "\n", "`class classname(baseclass):`\n", "\n", "For example, \n", "`class Flower(Plant):`\n", "\n", "Here we say that \n", "\"the class Flower is a subclass of the base class Plant.\"\n", "Plant may itself be a subclass of LivingThing \n", "\n", "\n", "attributes of the baseclass are inherited by the subclass\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class Plant:\n", " num_known = 0\n", " def __init__(self,common_name,latin_name=None):\n", " self.latin_name = latin_name\n", " self.common_name = common_name\n", " Plant.num_known += 1" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class Flower(Plant):\n", " has_pedals = True" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "p = Plant(\"poison ivy\")\n", "e = Flower(\"poppy\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "e.has_pedals" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "Plant.num_known " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "Flower.__bases__[0].__name__" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "instantiation of a Flower reuses the `__init__` from the Plant class. It also sets has pedals = `True` " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class Plant:\n", " num_known = 0\n", " def __init__(self,common_name,latin_name=None):\n", " self.latin_name = latin_name\n", " self.common_name = common_name\n", " Plant.num_known += 1\n", " def __str__(self):\n", " return \"I am a plant (%s)!\" % self.common_name\n", "\n", "class Flower(Plant):\n", " has_pedals = True\n", " \n", " def __str__(self):\n", " return \"I am a flower (%s)!\" % self.common_name" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "now the `__str__` method of Flower takes precedence over the `__str__` method of the parent class " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "f = Flower(\"rose\") ; print(f)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "p = Plant(\"oak\"); print(p)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class Flower(Plant):\n", " has_pedals = True\n", " \n", " def __init__(self,common_name,npedals=5,pedal_color=\"red\",latin_name=None):\n", " ## call the __init__ of the parent class\n", " Plant.__init__(self,common_name,latin_name=latin_name)\n", " self.npedals = npedals\n", " self.pedal_color = pedal_color\n", " \n", " def __str__(self):\n", " return \"I am a flower (%s)!\" % self.common_name" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "we can still use the parent class' `__init__`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "f = Flower(\"rose\") ; print(f)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "class A:\n", " def __init__(self):\n", " print(\"A\")\n", "class B(A):\n", " def __init__(self):\n", " A.__init__(self)\n", " print(\"B\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "a = A()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "b = B()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Multiple Inheritances\n", "\n", "`class Flower1(Plant,EdibleFood,SmellyStuff)`\n", "\n", "when executing a method the namespace of: \n", "\n", "- `Flower1` is searched first\n", "- `Plant` second (and it's baseclasses...and their baseclasses)\n", "- `EdibleFood` second (and it's baseclasses...and their baseclasses)\n", "- `SmellyStuff` second (and it's baseclasses...and their baseclasses)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Errors (& Handling)\n", "\n", "#### There are many different kinds of exceptions that can be raised by an error and each of them can be handled differently..." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "3.1415/0" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def this_fails():\n", " x = 3.1415/0\n", "try:\n", " this_fails()\n", "except ZeroDivisionError as detail:\n", " print('Handling run-time error:',detail )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`import exceptions`\n", "http://docs.python.org/library/exceptions.html\n", "\n", "
\n",
    "exception BaseException\n",
    "exception Exception\n",
    "exception StandardError\n",
    "exception ArithmeticError\n",
    "exception LookupError\n",
    "exception EnvironmentError\n",
    "exception AssertionError\n",
    "exception AttributeError\n",
    "exception EOFError\n",
    "exception GeneratorExit\n",
    "exception IOError\n",
    "exception ImportError\n",
    "exception IndexError\n",
    "exception KeyError\n",
    "exception KeyboardInterrupt\n",
    "exception MemoryError\n",
    "exception NameError\n",
    "exception OverflowError\n",
    "exception ReferenceError\n",
    "exception RuntimeError\n",
    "exception StopIteration\n",
    "exception SyntaxError\n",
    "exception SystemError\n",
    "exception SystemExit\n",
    "exception TypeError\n",
    "exception ValueError\n",
    "exception VMSError\n",
    "exception WindowsError\n",
    "exception ZeroDivisionError\n",
    "exception Warning\n",
    "exception UserWarning\n",
    "exception DeprecationWarning\n",
    "exception PendingDeprecationWarning\n",
    "exception SyntaxWarning\n",
    "exception RuntimeWarning\n",
    "exception FutureWarning\n",
    "exception ImportWarning\n",
    "
" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def divide(x, y):\n", " try:\n", " result = x / y\n", " except ZeroDivisionError:\n", " print(\"division by zero!\")\n", " else:\n", " print(\"result is\", result)\n", " finally:\n", " print(\"executing finally clause\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "divide(2,1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "divide(2,0)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "divide(\"2\",\"1\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Catch Multiple Error Types" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%%file catcherr.py \n", "import sys\n", "try:\n", " f = open('myfile.txt')\n", " s = f.readline()\n", " i = int(s.strip())\n", "except IOError as err:\n", " print(\"I/O error: %s\" % err)\n", "except ValueError:\n", " print(\"Could not convert data to an integer.\")\n", "except:\n", " print(\"Unexpected error:\", sys.exc_info()[0])\n", " raise" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> exc_info(...)\n", "\n", "> exc_info() -> (type, value, traceback)\n", " \n", " Return information about the most recent exception caught by an except\n", " clause in the current stack frame or in an older stack frame." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "run catcherr" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Raising Errors\n", "\n", "we can raise errors in our codes (which themselves might be caught upstream)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "a = \"cat food\"\n", "if a != \"spam\":\n", " raise NameError(\"anything that isn't spam breaks my code\") " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Errors are a family of classes (and subclasses)!\n", "
\n",
    "BaseException\n",
    " +-- SystemExit\n",
    " +-- KeyboardInterrupt\n",
    " +-- GeneratorExit\n",
    " +-- Exception\n",
    "      +-- StopIteration\n",
    "      +-- StandardError\n",
    "      |    +-- BufferError\n",
    "      |    +-- ArithmeticError\n",
    "      |    |    +-- FloatingPointError\n",
    "      |    |    +-- OverflowError\n",
    "      |    |    +-- ZeroDivisionError\n",
    "      |    +-- AssertionError\n",
    "      |    +-- AttributeError\n",
    "      |    +-- EnvironmentError\n",
    "      |    |    +-- IOError\n",
    "      |    |    +-- OSError\n",
    "      |    |         +-- WindowsError (Windows)\n",
    "      |    |         +-- VMSError (VMS)\n",
    "      |    +-- EOFError\n",
    "      |    +-- ImportError\n",
    "      |    +-- LookupError\n",
    "      |    |    +-- IndexError\n",
    "      |    |    +-- KeyError\n",
    "      |    +-- MemoryError\n",
    "      |    +-- NameError\n",
    "      |    |    +-- UnboundLocalError\n",
    "      |    +-- ReferenceError\n",
    "      |    +-- RuntimeError\n",
    "      |    |    +-- NotImplementedError\n",
    "      |    +-- SyntaxError\n",
    "      |    |    +-- IndentationError\n",
    "      |    |         +-- TabError\n",
    "      |    +-- SystemError\n",
    "      |    +-- TypeError\n",
    "      |    +-- ValueError\n",
    "      |         +-- UnicodeError\n",
    "      |              +-- UnicodeDecodeError\n",
    "      |              +-- UnicodeEncodeError\n",
    "      |              +-- UnicodeTranslateError\n",
    "      +-- Warning\n",
    "           +-- DeprecationWarning\n",
    "           +-- PendingDeprecationWarning\n",
    "           +-- RuntimeWarning\n",
    "           +-- SyntaxWarning\n",
    "           +-- UserWarning\n",
    "           +-- FutureWarning\n",
    "\t   +-- ImportWarning\n",
    "\t   +-- UnicodeWarning\n",
    "\t   +-- BytesWarning \n",
    "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## We can create our own exception classes by subclassing others (e.g., Exception)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import datetime" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class MyError(StopIteration):\n", " \n", " def __init__(self,value=None):\n", " ## call the baseclass Exception __init__\n", " Exception.__init__(self)\n", " self.value = value\n", " print(\"exception with %s at time %s\" % (self.value,datetime.datetime.now()))\n", "\n", " def __str__(self):\n", " return \"you said %s\" % self.value\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "raise MyError(\"darnit\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%debug" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%pdb" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.5.2" } }, "nbformat": 4, "nbformat_minor": 0 }