Last active
August 29, 2015 13:56
-
-
Save anandology/9223073 to your computer and use it in GitHub Desktop.
Advanced Python Training at LinkedIn -- Feb 26 - Mar 1, 2014
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "metadata": { | |
| "name": "" | |
| }, | |
| "nbformat": 3, | |
| "nbformat_minor": 0, | |
| "worksheets": [ | |
| { | |
| "cells": [ | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "# Advanced Python Training - Day 4\n", | |
| "Linked In<br/>\n", | |
| "Feb 26 - Mar 1, 2014<br/>\n", | |
| "<a href=\"http://anandology.com\">Anand Chitipothu</a>" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "Classes warmup - <http://anandology.com/apy/slides/classes.html>" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "# Problem 1\n", | |
| "class Foo:\n", | |
| " x = 1\n", | |
| "\n", | |
| "f1 = Foo()\n", | |
| "f2 = Foo()\n", | |
| "print Foo.x, f1.x, f2.x\n", | |
| "\n", | |
| "f2.x = 2\n", | |
| "print Foo.x, f1.x, f2.x\n", | |
| "\n", | |
| "Foo.x = 3\n", | |
| "print Foo.x, f1.x, f2.x" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "1 1 1\n", | |
| "1 1 2\n", | |
| "3 3 2\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 2 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "class Foo(object):\n", | |
| " x = 1\n", | |
| "\n", | |
| " def getx(self):\n", | |
| " return self.x\n", | |
| "\n", | |
| "f = Foo()\n", | |
| "print f.getx()\n", | |
| "\n", | |
| "# That is equivalant to:\n", | |
| "print Foo.getx(f)" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "1\n", | |
| "1\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 4 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "# Problem 2\n", | |
| "class Foo(object):\n", | |
| " x = 1\n", | |
| "\n", | |
| "def getx(self):\n", | |
| " return self.x\n", | |
| "\n", | |
| "Foo.getx = getx\n", | |
| "\n", | |
| "f = Foo()\n", | |
| "print f.getx()" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "1\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 5 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "# problem 6\n", | |
| "class Foo:\n", | |
| " print \"hello, world\"\n", | |
| " def square(x):\n", | |
| " return x*x\n", | |
| "\n", | |
| " a = square(10)\n", | |
| " print a\n", | |
| "\n", | |
| "print Foo.a" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "hello, world\n", | |
| "100\n", | |
| "100\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 6 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "class Foo:\n", | |
| " x = 1\n", | |
| "\n", | |
| "Foo.__dict__" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "metadata": {}, | |
| "output_type": "pyout", | |
| "prompt_number": 7, | |
| "text": [ | |
| "{'__doc__': None, '__module__': '__main__', 'x': 1}" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 7 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "Foo.__dict__['y'] = 2\n", | |
| "print Foo.y" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "2\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 8 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "f = Foo()\n", | |
| "f.__dict__" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "metadata": {}, | |
| "output_type": "pyout", | |
| "prompt_number": 9, | |
| "text": [ | |
| "{}" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 9 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "f.__class__" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "metadata": {}, | |
| "output_type": "pyout", | |
| "prompt_number": 10, | |
| "text": [ | |
| "__main__.Foo" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 10 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "f.x" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "metadata": {}, | |
| "output_type": "pyout", | |
| "prompt_number": 11, | |
| "text": [ | |
| "1" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 11 | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "**ducktyping**" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "def wordcount(fileobj):\n", | |
| " return len(fileobj.read().split())\n", | |
| "\n", | |
| "print wordcount(open(\"numbers.txt\"))" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "5\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 12 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "class FakeFile:\n", | |
| " def read(self):\n", | |
| " return \"a b c d e\"" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [], | |
| "prompt_number": 13 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "wordcount(FakeFile())" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "metadata": {}, | |
| "output_type": "pyout", | |
| "prompt_number": 14, | |
| "text": [ | |
| "5" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 14 | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "### Special Class Methods" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "**`__str__` and `__repr__`**" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "class Point:\n", | |
| " def __init__(self, x, y):\n", | |
| " self.x = x\n", | |
| " self.y = y\n", | |
| " \n", | |
| " def __str__(self):\n", | |
| " return \"({0}, {1})\".format(self.x, self.y)\n", | |
| " \n", | |
| " def __repr__(self):\n", | |
| " return \"Point(x={}, y={})\".format(self.x, self.y)\n", | |
| " \n", | |
| "p = Point(1, 2)\n", | |
| "print p\n", | |
| "\n", | |
| "print str(p)" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "(1, 2)\n", | |
| "(1, 2)\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 24 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "print \"1\", 1" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "1 1\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 20 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "print repr(\"1\"), repr(1)" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "'1' 1\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 21 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "[\"1\", 1]" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "metadata": {}, | |
| "output_type": "pyout", | |
| "prompt_number": 22, | |
| "text": [ | |
| "['1', 1]" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 22 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "[p]" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "metadata": {}, | |
| "output_type": "pyout", | |
| "prompt_number": 25, | |
| "text": [ | |
| "[Point(x=1, y=2)]" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 25 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "print p" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "(1, 2)\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 26 | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "**Problem** Write a class `Person` with firstname and lastname and add str and repr." | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "**Operators**" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "class Point:\n", | |
| " def __init__(self, x, y):\n", | |
| " self.x = x\n", | |
| " self.y = y\n", | |
| " \n", | |
| " def __str__(self):\n", | |
| " return \"({0}, {1})\".format(self.x, self.y)\n", | |
| " \n", | |
| " def __repr__(self):\n", | |
| " return \"Point(x={}, y={})\".format(self.x, self.y)\n", | |
| " \n", | |
| " def __add__(self, p):\n", | |
| " return Point(self.x+p.x, self.y+p.y)\n", | |
| " \n", | |
| "p1 = Point(2, 3)\n", | |
| "p2 = Point(3, 4)\n", | |
| "\n", | |
| "print p1 + p2" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "(5, 7)\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 31 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "x = 1\n", | |
| "y = 2\n", | |
| "x + y" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "metadata": {}, | |
| "output_type": "pyout", | |
| "prompt_number": 28, | |
| "text": [ | |
| "3" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 28 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "x.__add__(y)" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "metadata": {}, | |
| "output_type": "pyout", | |
| "prompt_number": 29, | |
| "text": [ | |
| "3" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 29 | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "**Problem** Change the `Point` class above to support `*` operator.\n", | |
| " \n", | |
| " >>> p = Point(2, 3)\n", | |
| " >>> p * 10\n", | |
| " Point(20, 30)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "**Container types**" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "x = [\"a\", \"b\", \"c\"]\n", | |
| "print x[1]" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "b\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 32 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "print x.__getitem__(1)" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "b\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 33 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "print len(x)" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "3\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 34 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "len(\"abce\")" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "metadata": {}, | |
| "output_type": "pyout", | |
| "prompt_number": 35, | |
| "text": [ | |
| "4" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 35 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "x.__len__()" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "metadata": {}, | |
| "output_type": "pyout", | |
| "prompt_number": 36, | |
| "text": [ | |
| "3" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 36 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "class yrange:\n", | |
| " def __init__(self, begin, end):\n", | |
| " self.begin = begin\n", | |
| " self.end = end\n", | |
| " \n", | |
| " def __len__(self):\n", | |
| " return self.end - self.begin\n", | |
| " \n", | |
| "y = yrange(5, 10)\n", | |
| "print len(y)" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "5\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 39 | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "**Problem** The the above `yrange` class work like a list by adding `__getitem__` method.\n", | |
| "\n", | |
| " >>> y = yrange(5, 10)\n", | |
| " >>> y[0]\n", | |
| " 5\n", | |
| " >>> y[3]\n", | |
| " 8\n", | |
| " >>> y[8]\n", | |
| " Traceback (most recent call last):\n", | |
| " ...\n", | |
| " IndexError: index out of range " | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "import functools\n", | |
| "\n", | |
| "def itemgetter(f):\n", | |
| " \"\"\"decorator to wrap __getitem__ to \n", | |
| " take care of negative indices and \n", | |
| " out of range errors.\n", | |
| " \"\"\"\n", | |
| " @functools.wraps(f)\n", | |
| " def g(self, index):\n", | |
| " if index < 0:\n", | |
| " index = len(self) + index\n", | |
| " if 0 <= index < len(self):\n", | |
| " return f(self, index)\n", | |
| " else:\n", | |
| " raise IndexError(\"index out of range\")\n", | |
| " return g\n", | |
| " \n", | |
| "class yrange:\n", | |
| " def __init__(self, begin, end):\n", | |
| " self.begin = begin\n", | |
| " self.end = end\n", | |
| " \n", | |
| " def __len__(self):\n", | |
| " return self.end - self.begin\n", | |
| " \n", | |
| " @itemgetter\n", | |
| " def __getitem__(self, index):\n", | |
| " return self.begin + index\n", | |
| " \n", | |
| "y = yrange(5, 10)\n", | |
| "print len(y)\n", | |
| "print y[0]\n", | |
| "print y[3]\n", | |
| "print y[-1]\n", | |
| "try:\n", | |
| " print y[8]\n", | |
| "except IndexError, e:\n", | |
| " print str(e)" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "5\n", | |
| "5\n", | |
| "8\n", | |
| "9\n", | |
| "index out of range\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 45 | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "**Problem** Write a class `Node` to represent a Node in HTML tree. It should work as shown in the examples below.\n", | |
| "\n", | |
| " >>> input = Node(\"input\", name=\"x\", type=\"text\", value=\"3\")\n", | |
| " >>> print input\n", | |
| " <input type=\"text\" name=\"x\" value=\"3\"/>\n", | |
| " >>> print repr(input)\n", | |
| " <Node input attrs={\"type\": \"text\", \"name\": \"x\", \"value\": \"3\"}>\n", | |
| " \n", | |
| " >>> input['type']\n", | |
| " 'text'\n", | |
| " >>> input['value'] = \"10\"\n", | |
| " >>> print input\n", | |
| " <input type=\"text\" name=\"x\" value=\"10\"/>\n", | |
| " >>> print Node(\"hr\")\n", | |
| " <hr/>\n", | |
| " >>> print Node(\"img\", src=\"a.jpg\")\n", | |
| " <img src=\"a.jpg\"/> " | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "**Properties**" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "class Person0:\n", | |
| " def __init__(self, fullname):\n", | |
| " self.fullname = fullname\n", | |
| " \n", | |
| "def hello(p):\n", | |
| " print \"Hello\", p.fullname\n", | |
| " \n", | |
| "# Lets say we are planning to replace the above class\n", | |
| "# with the one below.\n", | |
| "\n", | |
| "class Person:\n", | |
| " def __init__(self, firstname, lastname):\n", | |
| " self.firstname = firstname\n", | |
| " self.lastname = lastname\n", | |
| " \n", | |
| " @property\n", | |
| " def fullname(self):\n", | |
| " return \"{} {}\".format(self.firstname, self.lastname)\n", | |
| " \n", | |
| "p = Person(\"Foo\", \"Bar\")\n", | |
| "hello(p)" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "Hello Foo Bar\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 52 | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "**Problem** Write a class `File` that takes path as argument in the constuctor and provides basename, dirname and ext as properties.\n", | |
| "\n", | |
| " >>> f = File(\"/tmp/a.txt\")\n", | |
| " >>> f.basename\n", | |
| " 'a.txt'\n", | |
| " >>> f.dirname\n", | |
| " '/tmp'\n", | |
| " >>> f.ext\n", | |
| " 'txt'" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "import re\n", | |
| "class Person(object):\n", | |
| " def __init__(self, firstname, lastname, phone):\n", | |
| " self.firstname = firstname\n", | |
| " self.lastname = lastname\n", | |
| " self._phone = phone\n", | |
| " \n", | |
| " @property\n", | |
| " def fullname(self):\n", | |
| " return \"{} {}\".format(self.firstname, self.lastname)\n", | |
| "\n", | |
| " @property\n", | |
| " def phone(self):\n", | |
| " return self._phone\n", | |
| " \n", | |
| " @phone.setter\n", | |
| " def phone(self, value):\n", | |
| " if not re.match(\"[0-9]+\", value):\n", | |
| " raise ValueError(\"Invalid Phone number\")\n", | |
| " self._phone = value\n", | |
| " \n", | |
| " # The same thing can also be done as:\n", | |
| " def get_phone(self):\n", | |
| " return self._phone\n", | |
| " \n", | |
| " def set_phone(self, value):\n", | |
| " if not re.match(\"[0-9]+\", value):\n", | |
| " raise ValueError(\"Invalid Phone number\")\n", | |
| " self._phone = value\n", | |
| " \n", | |
| " phone2 = property(get_phone, set_phone)\n", | |
| "\n", | |
| "p = Person(\"Foo\", \"Bar\", \"1234\")\n", | |
| "print p.phone\n", | |
| "p.phone = \"bad-value\"\n", | |
| "print p.phone" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "ename": "ValueError", | |
| "evalue": "Invalid Phone number", | |
| "output_type": "pyerr", | |
| "traceback": [ | |
| "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", | |
| "\u001b[0;32m<ipython-input-65-f475fee4479a>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 33\u001b[0m \u001b[0mp\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mPerson\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Foo\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"Bar\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"1234\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 34\u001b[0m \u001b[0;32mprint\u001b[0m \u001b[0mp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mphone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 35\u001b[0;31m \u001b[0mp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mphone\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"bad-value\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 36\u001b[0m \u001b[0;32mprint\u001b[0m \u001b[0mp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mphone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
| "\u001b[0;32m<ipython-input-65-f475fee4479a>\u001b[0m in \u001b[0;36mphone\u001b[0;34m(self, value)\u001b[0m\n\u001b[1;32m 17\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mphone\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 18\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mre\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmatch\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"[0-9]+\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 19\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Invalid Phone number\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 20\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_phone\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 21\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", | |
| "\u001b[0;31mValueError\u001b[0m: Invalid Phone number" | |
| ] | |
| }, | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "1234\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 65 | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "### new-style and old-style classes" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "class A:\n", | |
| " pass\n", | |
| "\n", | |
| "class B(object):\n", | |
| " pass\n", | |
| "\n", | |
| "a = A()\n", | |
| "b = B()\n", | |
| "\n", | |
| "print type(a), type(b)" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "<type 'instance'> <class '__main__.B'>\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 67 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "a + 1" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "ename": "TypeError", | |
| "evalue": "unsupported operand type(s) for +: 'instance' and 'int'", | |
| "output_type": "pyerr", | |
| "traceback": [ | |
| "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", | |
| "\u001b[0;32m<ipython-input-68-a1bd27f4633f>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ma\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", | |
| "\u001b[0;31mTypeError\u001b[0m: unsupported operand type(s) for +: 'instance' and 'int'" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 68 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "b + 1" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "ename": "TypeError", | |
| "evalue": "unsupported operand type(s) for +: 'B' and 'int'", | |
| "output_type": "pyerr", | |
| "traceback": [ | |
| "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", | |
| "\u001b[0;32m<ipython-input-69-60661c9df6ee>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mb\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", | |
| "\u001b[0;31mTypeError\u001b[0m: unsupported operand type(s) for +: 'B' and 'int'" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 69 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "class A:\n", | |
| " @property\n", | |
| " def x(self):\n", | |
| " return 1\n", | |
| "\n", | |
| "class B(object):\n", | |
| " @property\n", | |
| " def x(self):\n", | |
| " return 1\n", | |
| " \n", | |
| "a = A()\n", | |
| "b = B()\n", | |
| "print a.x, b.x" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "1 1\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 71 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "a.x = 2" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [], | |
| "prompt_number": 72 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "print a.x" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "2\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 73 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "b.x = 2" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "ename": "AttributeError", | |
| "evalue": "can't set attribute", | |
| "output_type": "pyerr", | |
| "traceback": [ | |
| "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", | |
| "\u001b[0;32m<ipython-input-74-020d13f236c7>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mb\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", | |
| "\u001b[0;31mAttributeError\u001b[0m: can't set attribute" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 74 | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "**Descriptors**" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "class One(object):\n", | |
| " def __get__(self, obj, type):\n", | |
| " print \"__get__ called\", obj, One\n", | |
| " if obj is None:\n", | |
| " return self\n", | |
| " return 1\n", | |
| " \n", | |
| " def __repr__(self):\n", | |
| " return \"<one>\"\n", | |
| " \n", | |
| "class Foo(object):\n", | |
| " x = One()\n", | |
| " \n", | |
| " @property\n", | |
| " def y(self):\n", | |
| " return 2\n", | |
| " \n", | |
| " def __repr__(self):\n", | |
| " return \"Foo()\"\n", | |
| " \n", | |
| "f = Foo()\n", | |
| "print f.x\n", | |
| "print Foo.x" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "__get__ called Foo() <class '__main__.One'>\n", | |
| "1\n", | |
| "__get__ called None <class '__main__.One'>\n", | |
| "<one>\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 82 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "y = Foo.y\n", | |
| "\n", | |
| "print y.__get__(f, property)" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "2\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 84 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "import re\n", | |
| "re_email = re.compile(\".*@.*\")\n", | |
| "\n", | |
| "class Email(object):\n", | |
| " \"\"\"Descriptor class to validate email addresses.\n", | |
| " \"\"\"\n", | |
| " def __init__(self):\n", | |
| " self.value = None\n", | |
| " \n", | |
| " def __get__(self, obj, type):\n", | |
| " if obj is None:\n", | |
| " return self\n", | |
| " return self.value\n", | |
| " \n", | |
| " def __set__(self, obj, value):\n", | |
| " print \"__set__\", value\n", | |
| " if re_email.match(value):\n", | |
| " self.value = value\n", | |
| " else:\n", | |
| " raise ValueError(\"Invalid email\")\n", | |
| " \n", | |
| "class Person(object):\n", | |
| " email = Email()\n", | |
| " \n", | |
| "p = Person()\n", | |
| "print p.email\n", | |
| "p.email = \"[email protected]\"\n", | |
| "print p.email\n", | |
| "p.email = \"bad-email\"\n" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "ename": "ValueError", | |
| "evalue": "Invalid email", | |
| "output_type": "pyerr", | |
| "traceback": [ | |
| "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", | |
| "\u001b[0;32m<ipython-input-92-7b22aa81328e>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 27\u001b[0m \u001b[0mp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0memail\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"[email protected]\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 28\u001b[0m \u001b[0;32mprint\u001b[0m \u001b[0mp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0memail\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 29\u001b[0;31m \u001b[0mp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0memail\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"bad-email\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", | |
| "\u001b[0;32m<ipython-input-92-7b22aa81328e>\u001b[0m in \u001b[0;36m__set__\u001b[0;34m(self, obj, value)\u001b[0m\n\u001b[1;32m 18\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalue\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 19\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 20\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Invalid email\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 21\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 22\u001b[0m \u001b[0;32mclass\u001b[0m \u001b[0mPerson\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobject\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
| "\u001b[0;31mValueError\u001b[0m: Invalid email" | |
| ] | |
| }, | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "None\n", | |
| "__set__ [email protected]\n", | |
| "[email protected]\n", | |
| "__set__ bad-email\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 92 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "class my_property(object):\n", | |
| " def __init__(self, func):\n", | |
| " self.func = func\n", | |
| " print \"my_property.__init__\", self.func\n", | |
| " \n", | |
| " def __get__(self, obj, type):\n", | |
| " # convention used in descriptiors\n", | |
| " # to return the descirptor when accessed \n", | |
| " # from the class\n", | |
| " if obj is None:\n", | |
| " return self\n", | |
| " return self.func(obj)\n", | |
| "\n", | |
| "class Foo(object):\n", | |
| " #@my_property\n", | |
| " def x(self):\n", | |
| " print \"Foo.x function called\"\n", | |
| " return 1\n", | |
| " \n", | |
| " x = my_property(x)\n", | |
| " \n", | |
| "f = Foo()\n", | |
| "print f.x \n", | |
| "print f.x " | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "my_property.__init__ <function x at 0x102ca2578>\n", | |
| "Foo.x function called\n", | |
| "1\n", | |
| "Foo.x function called\n", | |
| "1\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 99 | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "**Problem** Write a descriptor `cached_property` that works like the property descriptor, but caches the result after calling the function once." | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "**Callable objects**" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "def square(x):\n", | |
| " return x*x" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [], | |
| "prompt_number": 100 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "square.__call__(3)" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "metadata": {}, | |
| "output_type": "pyout", | |
| "prompt_number": 101, | |
| "text": [ | |
| "9" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 101 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "class Square:\n", | |
| " def __call__(self, x):\n", | |
| " return x*x\n", | |
| " \n", | |
| "sq = Square()\n", | |
| "print sq(4)" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "16\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 102 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "def make_adder(x):\n", | |
| " def adder(y):\n", | |
| " return x+y\n", | |
| " return adder\n", | |
| "\n", | |
| "add5 = make_adder(5)\n", | |
| "print add5(3)" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "8\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 103 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "class Adder(object):\n", | |
| " def __init__(self, x):\n", | |
| " self.x = x\n", | |
| " def __call__(self, y):\n", | |
| " return self.x + y\n", | |
| " \n", | |
| "add5 = Adder(5)\n", | |
| "print add5(3)\n", | |
| "print add5.x\n", | |
| "add5.x = 2\n", | |
| "print add5(7)" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "8\n", | |
| "5\n", | |
| "9\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 111 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "Adder.__call__" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "metadata": {}, | |
| "output_type": "pyout", | |
| "prompt_number": 107, | |
| "text": [ | |
| "<unbound method Adder.__call__>" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 107 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "Adder.__class__" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "metadata": {}, | |
| "output_type": "pyout", | |
| "prompt_number": 108, | |
| "text": [ | |
| "type" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 108 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "type.__call__(Adder, 5)" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "metadata": {}, | |
| "output_type": "pyout", | |
| "prompt_number": 109, | |
| "text": [ | |
| "<__main__.Adder at 0x102ca3f10>" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 109 | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "Memoize as a class." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "class memoize:\n", | |
| " def __init__(self, func):\n", | |
| " self.func = func\n", | |
| " self.cache = {}\n", | |
| " \n", | |
| " def reset_cache(self):\n", | |
| " self.cache.clear()\n", | |
| " \n", | |
| " def __call__(self, *args):\n", | |
| " if args not in self.cache:\n", | |
| " self.cache[args] = self.func(*args)\n", | |
| " return self.cache[args]\n", | |
| " \n", | |
| "@memoize\n", | |
| "def square(n):\n", | |
| " print \"square\", n\n", | |
| " return n*n\n", | |
| " \n", | |
| "print square(2)\n", | |
| "print square(2)\n", | |
| "print square(2)\n", | |
| "square.reset_cache()\n", | |
| "print square(2)\n", | |
| "print square(2)\n", | |
| "print square(2)\n" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "square 2\n", | |
| "4\n", | |
| "4\n", | |
| "4\n", | |
| "square 2\n", | |
| "4\n", | |
| "4\n", | |
| "4\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 114 | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "**Meta classes**" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "x = 1\n", | |
| "print type(x)" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "<type 'int'>\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 116 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "print type(int)" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "<type 'type'>\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 117 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "print type(type)" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "<type 'type'>\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 119 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "Point = type(\"Point\", (object,), {\"x\": 0, \"y\": 0})" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [], | |
| "prompt_number": 120 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "Point" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "metadata": {}, | |
| "output_type": "pyout", | |
| "prompt_number": 121, | |
| "text": [ | |
| "__main__.Point" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 121 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "Point.x" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "metadata": {}, | |
| "output_type": "pyout", | |
| "prompt_number": 122, | |
| "text": [ | |
| "0" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 122 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "p = Point()" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [], | |
| "prompt_number": 123 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "class Point(object):\n", | |
| " x = 0\n", | |
| " y = 0" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [], | |
| "prompt_number": 124 | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "The above snippet is eqvivalant to " | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "Point = type(\"Point\", (object,), {\"x\": 0, \"y\": 0})" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [], | |
| "prompt_number": 125 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "A = type(\"A\", (object,), {\"x\": 0})\n", | |
| "B = type(\"B\", (A,), {\"y\": 1})" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [], | |
| "prompt_number": 127 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "B" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "metadata": {}, | |
| "output_type": "pyout", | |
| "prompt_number": 128, | |
| "text": [ | |
| "__main__.B" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 128 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "B.x" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "metadata": {}, | |
| "output_type": "pyout", | |
| "prompt_number": 129, | |
| "text": [ | |
| "0" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 129 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "B.y" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "metadata": {}, | |
| "output_type": "pyout", | |
| "prompt_number": 130, | |
| "text": [ | |
| "1" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 130 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "B.__bases__" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "metadata": {}, | |
| "output_type": "pyout", | |
| "prompt_number": 131, | |
| "text": [ | |
| "(__main__.A,)" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 131 | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "Since type is a class, it should be possible to subclass it." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "class type2(type):\n", | |
| " pass" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [], | |
| "prompt_number": 132 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "A = type2(\"A\", (), {})" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [], | |
| "prompt_number": 133 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "A" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "metadata": {}, | |
| "output_type": "pyout", | |
| "prompt_number": 134, | |
| "text": [ | |
| "__main__.A" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 134 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "a = A()" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [], | |
| "prompt_number": 135 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "print type(a)" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "<class '__main__.A'>\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 136 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "print type(A)" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "<class '__main__.type2'>\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 137 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "class type2(type):\n", | |
| " def __init__(self, name, bases, attrs):\n", | |
| " print \"type2.__init__\", name, bases, attrs\n", | |
| " type.__init__(self, name, bases, attrs)" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [], | |
| "prompt_number": 138 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "A = type2(\"A\", (), {})" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "type2.__init__ A () {}\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 139 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "class B(A):\n", | |
| " pass" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "type2.__init__ B (<class '__main__.A'>,) {'__module__': '__main__'}\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 140 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "class A(object):\n", | |
| " __metaclass__ = type2" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "type2.__init__ A (<type 'object'>,) {'__module__': '__main__', '__metaclass__': <class '__main__.type2'>}\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 141 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [ | |
| "class B(A): pass" | |
| ], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "stream": "stdout", | |
| "text": [ | |
| "type2.__init__ B (<class '__main__.A'>,) {'__module__': '__main__'}\n" | |
| ] | |
| } | |
| ], | |
| "prompt_number": 142 | |
| }, | |
| { | |
| "cell_type": "code", | |
| "collapsed": false, | |
| "input": [], | |
| "language": "python", | |
| "metadata": {}, | |
| "outputs": [] | |
| } | |
| ], | |
| "metadata": {} | |
| } | |
| ] | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment