Last active
December 17, 2015 17:49
-
-
Save anandology/5648714 to your computer and use it in GitHub Desktop.
Notes from Advanced Python workshop
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": "3 - Classes (Advanced Python Workshop)" | |
}, | |
"nbformat": 3, | |
"nbformat_minor": 0, | |
"worksheets": [ | |
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Classes" | |
] | |
}, | |
{ | |
"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": [ | |
"# problem 4\n", | |
"class A:\n", | |
" x = 1\n", | |
" def f(self):\n", | |
" return self.x\n", | |
"\n", | |
"class B(A):\n", | |
" x = 2\n", | |
" def g(self):\n", | |
" return self.x\n", | |
"\n", | |
"a = A()\n", | |
"b = B()\n", | |
"\n", | |
"print a.f()\n", | |
"print b.f(), b.g()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"1\n", | |
"2 2\n" | |
] | |
} | |
], | |
"prompt_number": 3 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# problem 7\n", | |
"x = 1\n", | |
"\n", | |
"class Foo:\n", | |
" a = x\n", | |
" x = 2\n", | |
" print a, x\n", | |
"\n", | |
"print x" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"1 2\n", | |
"1\n" | |
] | |
} | |
], | |
"prompt_number": 4 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### Example: Timer class" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Problem:** Write a `Timer` class.\n", | |
"\n", | |
" \n", | |
" class Timer:\n", | |
" pass\n", | |
"\n", | |
" def timepass():\n", | |
" for i in range(10000):\n", | |
" for j in range(1000):\n", | |
" x = i*j\n", | |
"\n", | |
" t = Timer()\n", | |
" t.start()\n", | |
" timepass()\n", | |
" t.stop()\n", | |
" print \"took %f seconds\" % t.elapsed" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Ducktyping**" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%%file numbers.txt\n", | |
"one\n", | |
"two\n", | |
"three\n", | |
"four\n", | |
"five" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Writing numbers.txt\n" | |
] | |
} | |
], | |
"prompt_number": 10 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def wordcount(fileobj):\n", | |
" lc = len(fileobj.readlines())\n", | |
" fileobj.seek(0)\n", | |
" wc = len(fileobj.read().split())\n", | |
" fileobj.seek(0)\n", | |
" cc = len(fileobj.read())\n", | |
" return lc, wc, cc\n", | |
"\n", | |
"print wordcount(open(\"numbers.txt\"))\n", | |
"\n", | |
"class FakeFile:\n", | |
" def read(self):\n", | |
" return \"one\\ntwo\\nthree\\n\"\n", | |
" def readlines(self):\n", | |
" return [\"one\\n\", \"two\\n\", \"three\\n\"]\n", | |
" def seek(self, pos):\n", | |
" pass\n", | |
"\n", | |
"print wordcount(FakeFile())\n", | |
"\n", | |
"class Foo: pass\n", | |
"f = Foo()\n", | |
"\n", | |
"f.read = lambda: \"\"\n", | |
"f.readlines = lambda: []\n", | |
"f.seek = lambda n: 0\n", | |
"print wordcount(f)\n", | |
" " | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"(5, 5, 23)\n", | |
"(3, 3, 14)\n", | |
"(0, 0, 0)\n" | |
] | |
} | |
], | |
"prompt_number": 14 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Problem:** Write a class `UpperCaseFile`, that takes a fileobj as argument and behaves like a file, but returns everything in uppercase when read.\n", | |
"\n", | |
" f = UpperCaseFile(open(\"numbers.txt\"))\n", | |
" line = f.readline() # should give \"ONE\\n\"\n", | |
" lines = f.readlines() # should give [\"TWO\\n\", \"THREE\\n\", \"FOUR\\n\", \"FIVE\\n\"]\n", | |
"\n", | |
" f = UpperCaseFile(open(\"numbers.txt\"))\n", | |
" print wordcount(f) # should be same as wordcount(open(\"numbers.txt\"))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"There is a `StringIO` class in `StringIO` module that give file like interface to in-memory object." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"from StringIO import StringIO\n", | |
"f = StringIO()\n", | |
"f.write(\"hello\\nworld\\n\")\n", | |
"f.seek(0)\n", | |
"print f.read()\n", | |
"\n", | |
"f.seek(0)\n", | |
"print wordcount(f)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"hello\n", | |
"world\n", | |
"\n", | |
"(2, 2, 12)\n" | |
] | |
} | |
], | |
"prompt_number": 18 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Special Class Methods" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"x = 1\n", | |
"print x" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"1\n" | |
] | |
} | |
], | |
"prompt_number": 19 | |
}, | |
{ | |
"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 \"(%s, %s)\" % (self.x, self.y)\n", | |
"\n", | |
"p = Point(2, 3)\n", | |
"print p" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"(2, 3)\n" | |
] | |
} | |
], | |
"prompt_number": 33 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"print repr(1)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"1\n" | |
] | |
} | |
], | |
"prompt_number": 27 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"print repr(\"hello\")" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"'hello'\n" | |
] | |
} | |
], | |
"prompt_number": 28 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"print \"hello\"" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"hello\n" | |
] | |
} | |
], | |
"prompt_number": 29 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"[1, 2, \"3, 4\"]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 31, | |
"text": [ | |
"[1, 2, '3, 4']" | |
] | |
} | |
], | |
"prompt_number": 31 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"print p" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"(2, 3)\n" | |
] | |
} | |
], | |
"prompt_number": 35 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"print [p]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"[<__main__.Point instance at 0x101fa2f38>]\n" | |
] | |
} | |
], | |
"prompt_number": 36 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"print repr(p)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"<__main__.Point instance at 0x101fa2f38>\n" | |
] | |
} | |
], | |
"prompt_number": 37 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"We need to implement `__repr__` to fix that." | |
] | |
}, | |
{ | |
"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 \"(%s, %s)\" % (self.x, self.y)\n", | |
" \n", | |
" def __repr__(self):\n", | |
" return \"Point(%s, %s)\" % (self.x, self.y)\n", | |
"\n", | |
"p = Point(2, 3)\n", | |
"print p, [p, \"hello\", (2, 3), 5]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"(2, 3) [Point(2, 3), 'hello', (2, 3), 5]\n" | |
] | |
} | |
], | |
"prompt_number": 41 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"#### Emulating Container Types" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# Do you know what happens when you do this?\n", | |
"\n", | |
"x = [1, 2, 3, 4]\n", | |
"print x[1]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"2\n" | |
] | |
} | |
], | |
"prompt_number": 42 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"x.__getitem__(1)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 43, | |
"text": [ | |
"2" | |
] | |
} | |
], | |
"prompt_number": 43 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"x = xrange(2, 8)\n", | |
"print len(x)\n", | |
"print x[3]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"6\n", | |
"5\n" | |
] | |
} | |
], | |
"prompt_number": 44 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"x.__len__()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 45, | |
"text": [ | |
"6" | |
] | |
} | |
], | |
"prompt_number": 45 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"#### Example: yrange\n", | |
"\n", | |
"Lets write a class `yrange` that behaves like built-in class `xrange`." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"#### Example: `Node` class" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class yrange:\n", | |
" def __init__(self, start, stop):\n", | |
" self.start = start\n", | |
" self.stop = stop\n", | |
" \n", | |
" def __len__(self):\n", | |
" return self.stop - self.start\n", | |
" \n", | |
" def __getitem__(self, index):\n", | |
" return self.start + index\n", | |
"\n", | |
"y = yrange(2, 8)\n", | |
"print len(y)\n", | |
"print y[3]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"6\n", | |
"5\n" | |
] | |
} | |
], | |
"prompt_number": 46 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Problem:** Implement a Node class that allows accessing properties like a dictionary.\n", | |
"\n", | |
" class Node:\n", | |
" def __init__(self, tagname, **attrs):\n", | |
" self.tagname = tagname\n", | |
"\n", | |
" x = Node(\"input\", type='text', name='x', id='id_x')\n", | |
" x['class'] = 'required'\n", | |
" x['value'] = 'foo'\n", | |
"\n", | |
" print x['name'], x['value']\n", | |
" print x" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"## Command library using classes" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 48 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%%file command1.py\n", | |
"class Command:\n", | |
" def run(self, filenames):\n", | |
" lines = self.readfiles(filenames)\n", | |
" lines = self.generate_output(lines)\n", | |
" self.printlines(lines)\n", | |
" \n", | |
" def process_line(self, line):\n", | |
" \"\"\"All bases classes should implement this.\"\"\"\n", | |
" raise NotImplementedError()\n", | |
"\n", | |
" def generate_output(self, lines):\n", | |
" for line in lines:\n", | |
" for outline in self.process_line(line):\n", | |
" yield outline\n", | |
"\n", | |
" def readfiles(self, filenames):\n", | |
" for f in filenames:\n", | |
" for line in open(f):\n", | |
" yield line\n", | |
"\n", | |
" def printlines(self, lines):\n", | |
" for line in lines:\n", | |
" print line.strip(\"\\n\")\n", | |
" \n" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Overwriting command1.py\n" | |
] | |
} | |
], | |
"prompt_number": 52 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%%file uppercase1.py\n", | |
"from command1 import Command\n", | |
"\n", | |
"class UpperCase(Command):\n", | |
" def process_line(self, line):\n", | |
" yield line.upper()\n", | |
"\n", | |
"if __name__ == \"__main__\":\n", | |
" import sys\n", | |
" cmd = UpperCase()\n", | |
" cmd.run(sys.argv[1:])" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Writing uppercase1.py\n" | |
] | |
} | |
], | |
"prompt_number": 50 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"!python uppercase1.py uppercase1.py" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"FROM COMMAND1 IMPORT COMMAND\r\n", | |
"\r\n", | |
"CLASS UPPERCASE(COMMAND):\r\n", | |
" DEF PROCESS_LINE(SELF, LINE):\r\n", | |
" YIELD LINE.UPPER()\r\n", | |
"\r\n", | |
"IF __NAME__ == \"__MAIN__\":\r\n", | |
" IMPORT SYS\r\n", | |
" CMD = UPPERCASE()\r\n", | |
" CMD.RUN(SYS.ARGV[1:])\r\n" | |
] | |
} | |
], | |
"prompt_number": 53 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%%file grep2.py\n", | |
"from command1 import Command\n", | |
"\n", | |
"class Grep(Command):\n", | |
" def __init__(self, pattern):\n", | |
" self.pattern = pattern\n", | |
" \n", | |
" def process_line(self, line):\n", | |
" if self.pattern in line:\n", | |
" yield line\n", | |
" \n", | |
"if __name__ == \"__main__\":\n", | |
" import sys\n", | |
" cmd = Grep(sys.argv[1])\n", | |
" cmd.run(sys.argv[2:])" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Writing grep2.py\n" | |
] | |
} | |
], | |
"prompt_number": 54 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"!python grep2.py def grep2.py" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
" def __init__(self, pattern):\r\n", | |
" def process_line(self, line):\r\n" | |
] | |
} | |
], | |
"prompt_number": 55 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Problem:** Write a script `replace.py` using `Command` class to replace a `pattern` with a `replacement` in given files. The script will get the pattern and replacement as first two arguments, followed by one or more files as input.\n", | |
"\n", | |
" python replace.py def define grep2.py command1.py" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Lets try to improve the `Command` class to handle to make it more generic." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%%file command2.py\n", | |
"\"\"\"A new approach to writing Command class.\n", | |
"\"\"\"\n", | |
"\n", | |
"class Command:\n", | |
" def run(self, filenames):\n", | |
" for filename in filenames:\n", | |
" self.process_file(filename)\n", | |
" \n", | |
" def process_file(self, filename):\n", | |
" for line in open(filename):\n", | |
" process_line(line)\n", | |
"\n", | |
" def process_line(self, line):\n", | |
" \"\"\"All bases classes should implement this.\"\"\"\n", | |
" raise NotImplementedError()\n", | |
"\n", | |
"class UpperCase(Command):\n", | |
" def process_line(self, line):\n", | |
" print line.upper()\n", | |
" \n", | |
"class WordCount(Command):\n", | |
" def process_file(self, filename):\n", | |
" lc = len(open(filename).readlines())\n", | |
" wc = len(open(filename).read().split())\n", | |
" cc = len(open(filename).read())\n", | |
" print lc, wc, cc, filename\n", | |
" \n", | |
"cmd = WordCount()\n", | |
"cmd.run([\"command1.py\", \"command2.py\"])" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Writing command2.py\n" | |
] | |
} | |
], | |
"prompt_number": 56 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"!python command2.py" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"20 47 544 command1.py\r\n", | |
"29 68 808 command2.py\r\n" | |
] | |
} | |
], | |
"prompt_number": 57 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Understanding Methods" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class Foo:\n", | |
" x = 1\n", | |
" def getx(self):\n", | |
" return self.x\n", | |
" \n", | |
"foo = Foo()\n", | |
"print foo.getx()\n", | |
"\n", | |
"print Foo.getx(foo)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"1\n", | |
"1\n" | |
] | |
} | |
], | |
"prompt_number": 2 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"Foo.getx" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 3, | |
"text": [ | |
"<unbound method Foo.getx>" | |
] | |
} | |
], | |
"prompt_number": 3 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"foo.getx" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 4, | |
"text": [ | |
"<bound method Foo.getx of <__main__.Foo instance at 0x101f9f3f8>>" | |
] | |
} | |
], | |
"prompt_number": 4 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def add(x, y):\n", | |
" return x+y" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 5 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def make_adder(x):\n", | |
" def adder(y):\n", | |
" return add(x, y)\n", | |
" return adder\n", | |
"\n", | |
"add5 = make_adder(5)\n", | |
"print add5(6)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"11\n" | |
] | |
} | |
], | |
"prompt_number": 7 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def bindself(method, self):\n", | |
" \"\"\"Returns a new function with self already bound\"\"\"\n", | |
" def f(*a, **kw):\n", | |
" return method(self, *a, **kw)\n", | |
" return f\n", | |
"\n", | |
"f = bindself(Foo.getx, foo)\n", | |
"f()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 8, | |
"text": [ | |
"1" | |
] | |
} | |
], | |
"prompt_number": 8 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### Looking inside objects" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class Foo:\n", | |
" x = 1\n", | |
" \n", | |
" def getx(self):\n", | |
" return self.x\n", | |
"\n", | |
"foo = Foo()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 10 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"Foo" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 11, | |
"text": [ | |
"__main__.Foo" | |
] | |
} | |
], | |
"prompt_number": 11 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"dir(Foo)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 12, | |
"text": [ | |
"['__doc__', '__module__', 'getx', 'x']" | |
] | |
} | |
], | |
"prompt_number": 12 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"Foo.__dict__" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 13, | |
"text": [ | |
"{'__doc__': None,\n", | |
" '__module__': '__main__',\n", | |
" 'getx': <function __main__.getx>,\n", | |
" 'x': 1}" | |
] | |
} | |
], | |
"prompt_number": 13 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"Foo.__dict__['x'] = 2\n", | |
"Foo.x" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 14, | |
"text": [ | |
"2" | |
] | |
} | |
], | |
"prompt_number": 14 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"Foo.__dict__['y'] = 3\n", | |
"Foo.y" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 15, | |
"text": [ | |
"3" | |
] | |
} | |
], | |
"prompt_number": 15 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# Lets try to find how add5 is storing value of x\n", | |
"dir(add5)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 17, | |
"text": [ | |
"['__call__',\n", | |
" '__class__',\n", | |
" '__closure__',\n", | |
" '__code__',\n", | |
" '__defaults__',\n", | |
" '__delattr__',\n", | |
" '__dict__',\n", | |
" '__doc__',\n", | |
" '__format__',\n", | |
" '__get__',\n", | |
" '__getattribute__',\n", | |
" '__globals__',\n", | |
" '__hash__',\n", | |
" '__init__',\n", | |
" '__module__',\n", | |
" '__name__',\n", | |
" '__new__',\n", | |
" '__reduce__',\n", | |
" '__reduce_ex__',\n", | |
" '__repr__',\n", | |
" '__setattr__',\n", | |
" '__sizeof__',\n", | |
" '__str__',\n", | |
" '__subclasshook__',\n", | |
" 'func_closure',\n", | |
" 'func_code',\n", | |
" 'func_defaults',\n", | |
" 'func_dict',\n", | |
" 'func_doc',\n", | |
" 'func_globals',\n", | |
" 'func_name']" | |
] | |
} | |
], | |
"prompt_number": 17 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def inc(x, amount=1): return x+amount" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 19 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"inc.func_defaults" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 20, | |
"text": [ | |
"(1,)" | |
] | |
} | |
], | |
"prompt_number": 20 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### How Python stores variables?" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"x = 1 # what does this mean?" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 21 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"g = globals()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 22 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"g['x']" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 23, | |
"text": [ | |
"1" | |
] | |
} | |
], | |
"prompt_number": 23 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"g['x'] = 2" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 24 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"x" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 25, | |
"text": [ | |
"2" | |
] | |
} | |
], | |
"prompt_number": 25 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### Understanding Function Calls" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def add(x, y): return x+y" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 28 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"add(5, 4)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 29, | |
"text": [ | |
"9" | |
] | |
} | |
], | |
"prompt_number": 29 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"d = [1, 2, 3]\n", | |
"d[2]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 30, | |
"text": [ | |
"3" | |
] | |
} | |
], | |
"prompt_number": 30 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"Foo" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 31, | |
"text": [ | |
"__main__.Foo" | |
] | |
} | |
], | |
"prompt_number": 31 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"Foo()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 32, | |
"text": [ | |
"<__main__.Foo instance at 0x102f49050>" | |
] | |
} | |
], | |
"prompt_number": 32 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class Adder:\n", | |
" def __init__(self, x):\n", | |
" self.x = x\n", | |
" \n", | |
" def __call__(self, y):\n", | |
" return add(self.x, y)\n", | |
" \n", | |
"add5 = Adder(5)\n", | |
"print add5(6)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"11\n" | |
] | |
} | |
], | |
"prompt_number": 34 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Problem:** Write `timeit` decorator as a class.\n", | |
"\n", | |
" class timeit:\n", | |
" ....\n", | |
"\n", | |
" @timeit\n", | |
" def timepass():\n", | |
" for i in range(10000):\n", | |
" for j in range(1000):\n", | |
" x = i*j\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### Understanding Atributes" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class Foo(object):\n", | |
" x = 1\n", | |
"foo = Foo()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 41 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"foo.x = 1\n", | |
"foo.x" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 42, | |
"text": [ | |
"1" | |
] | |
} | |
], | |
"prompt_number": 42 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"getattr(foo, \"x\")" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 46, | |
"text": [ | |
"1" | |
] | |
} | |
], | |
"prompt_number": 46 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class Attr:\n", | |
" def __getattr__(self, name):\n", | |
" return name.upper()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 47 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"a = Attr()\n", | |
"a.x" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 48, | |
"text": [ | |
"'X'" | |
] | |
} | |
], | |
"prompt_number": 48 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"a.y" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 49, | |
"text": [ | |
"'Y'" | |
] | |
} | |
], | |
"prompt_number": 49 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"a.foo" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 50, | |
"text": [ | |
"'FOO'" | |
] | |
} | |
], | |
"prompt_number": 50 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"getattr(a, \"x\")" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 51, | |
"text": [ | |
"'X'" | |
] | |
} | |
], | |
"prompt_number": 51 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Old-Style vs. New-Style Classes" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"x = 1\n", | |
"type(x)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 52, | |
"text": [ | |
"int" | |
] | |
} | |
], | |
"prompt_number": 52 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"type(int)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 53, | |
"text": [ | |
"type" | |
] | |
} | |
], | |
"prompt_number": 53 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class Foo: pass" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 54 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"type(Foo)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 55, | |
"text": [ | |
"classobj" | |
] | |
} | |
], | |
"prompt_number": 55 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"type(file)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 56, | |
"text": [ | |
"type" | |
] | |
} | |
], | |
"prompt_number": 56 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class Foo(object): pass\n", | |
"\n", | |
"type(Foo)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 57, | |
"text": [ | |
"type" | |
] | |
} | |
], | |
"prompt_number": 57 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class Foo(object): \n", | |
" def __len__(self): return 4" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 58 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"foo = Foo()\n", | |
"len(foo)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 59, | |
"text": [ | |
"4" | |
] | |
} | |
], | |
"prompt_number": 59 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"foo.__len__ = lambda: 5" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 60 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"len(foo)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 61, | |
"text": [ | |
"4" | |
] | |
} | |
], | |
"prompt_number": 61 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class Bar:\n", | |
" def __len__(self): return 4\n", | |
"\n", | |
"bar = Bar()\n", | |
"len(bar)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 62, | |
"text": [ | |
"4" | |
] | |
} | |
], | |
"prompt_number": 62 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"bar.__len__ = lambda: 5" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 63 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"len(bar)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 64, | |
"text": [ | |
"5" | |
] | |
} | |
], | |
"prompt_number": 64 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class Bar:\n", | |
" x = 1\n", | |
" def getx(self): return self.x\n", | |
" \n", | |
"bar = Bar()\n", | |
"print bar.getx()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"1\n" | |
] | |
} | |
], | |
"prompt_number": 68 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# What does this mean? bar.getx()\n", | |
"# f = bar.getx\n", | |
"# f()\n", | |
"\n", | |
"# What what does x[1]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 69 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Properties" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class Person(object):\n", | |
" firstname = \"Foo\"\n", | |
" lastname = \"Bar\"\n", | |
" _phonenumber = \"0\"\n", | |
"\n", | |
" @property \n", | |
" def fullname(self):\n", | |
" return self.firstname + \" \" + self.lastname\n", | |
"\n", | |
" @property\n", | |
" def phone(self):\n", | |
" return self._phonenumber\n", | |
" \n", | |
" @phone.setter\n", | |
" def phone(self, value):\n", | |
" if len(value) != 10:\n", | |
" raise ValueError(\"Invalid Phone number\")\n", | |
" self._phonenumber = value\n", | |
" \n", | |
" #phone = property(_get_phone, _set_phone)\n", | |
" \n", | |
"p = Person()\n", | |
"print p.fullname\n", | |
"print p.phone\n", | |
"p.phone = \"1234567890\"\n", | |
"print p.phone" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Foo Bar\n", | |
"0\n", | |
"1234567890\n" | |
] | |
} | |
], | |
"prompt_number": 87 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"dir(Person)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 88, | |
"text": [ | |
"['__class__',\n", | |
" '__delattr__',\n", | |
" '__dict__',\n", | |
" '__doc__',\n", | |
" '__format__',\n", | |
" '__getattribute__',\n", | |
" '__hash__',\n", | |
" '__init__',\n", | |
" '__module__',\n", | |
" '__new__',\n", | |
" '__reduce__',\n", | |
" '__reduce_ex__',\n", | |
" '__repr__',\n", | |
" '__setattr__',\n", | |
" '__sizeof__',\n", | |
" '__str__',\n", | |
" '__subclasshook__',\n", | |
" '__weakref__',\n", | |
" '_phonenumber',\n", | |
" 'firstname',\n", | |
" 'fullname',\n", | |
" 'lastname',\n", | |
" 'phone']" | |
] | |
} | |
], | |
"prompt_number": 88 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"Person.phone" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 89, | |
"text": [ | |
"<property at 0x102f5dcb0>" | |
] | |
} | |
], | |
"prompt_number": 89 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"p.phone" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 90, | |
"text": [ | |
"'1234567890'" | |
] | |
} | |
], | |
"prompt_number": 90 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"p.firstname" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 91, | |
"text": [ | |
"'Foo'" | |
] | |
} | |
], | |
"prompt_number": 91 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"p.__dict__" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 92, | |
"text": [ | |
"{'_phonenumber': '1234567890'}" | |
] | |
} | |
], | |
"prompt_number": 92 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"Person.__dict__" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 93, | |
"text": [ | |
"<dictproxy {'__dict__': <attribute '__dict__' of 'Person' objects>,\n", | |
" '__doc__': None,\n", | |
" '__module__': '__main__',\n", | |
" '__weakref__': <attribute '__weakref__' of 'Person' objects>,\n", | |
" '_phonenumber': '0',\n", | |
" 'firstname': 'Foo',\n", | |
" 'fullname': <property at 0x102f5de10>,\n", | |
" 'lastname': 'Bar',\n", | |
" 'phone': <property at 0x102f5dcb0>}>" | |
] | |
} | |
], | |
"prompt_number": 93 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"Person.phone.__get__(p)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 95, | |
"text": [ | |
"'1234567890'" | |
] | |
} | |
], | |
"prompt_number": 95 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Person.phone is a property object, but p.phone gives us a string value instead of a property." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class SimpleDescriptor(object):\n", | |
" def __get__(self, obj, type=None):\n", | |
" if obj is None:\n", | |
" return self\n", | |
" else:\n", | |
" return 1\n", | |
"\n", | |
"class Foo:\n", | |
" x = SimpleDescriptor()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 99 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"Foo.x" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 100, | |
"text": [ | |
"<__main__.SimpleDescriptor at 0x102f5c2d0>" | |
] | |
} | |
], | |
"prompt_number": 100 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"foo = Foo()\n", | |
"foo.x" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 101, | |
"text": [ | |
"1" | |
] | |
} | |
], | |
"prompt_number": 101 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Lets try to implement property class." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class my_property(object):\n", | |
" def __init__(self, getter):\n", | |
" self.getter = getter\n", | |
" \n", | |
" def __get__(self, obj, type=None):\n", | |
" if obj is None:\n", | |
" return self\n", | |
" else:\n", | |
" return self.getter(obj)\n", | |
" \n", | |
"class Person:\n", | |
" @my_property\n", | |
" def fullname(self):\n", | |
" print \"fulname called\"\n", | |
" return \"Foo Bar\"\n", | |
"\n", | |
"p = Person()\n", | |
"print Person.fullname\n", | |
"print p.fullname\n", | |
"print p.fullname" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"<__main__.my_property object at 0x102f67490>\n", | |
"fulname called\n", | |
"Foo Bar\n", | |
"fulname called\n", | |
"Foo Bar\n" | |
] | |
} | |
], | |
"prompt_number": 105 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class lazy_property(object):\n", | |
" def __init__(self, getter):\n", | |
" self.getter = getter\n", | |
" \n", | |
" def __get__(self, obj, type=None):\n", | |
" if obj is None:\n", | |
" return self\n", | |
" value = self.getter(obj)\n", | |
" obj.__dict__[self.getter.__name__] = value\n", | |
" return value\n", | |
" \n", | |
"class Person:\n", | |
" def __init__(self, first, last):\n", | |
" self.first = first\n", | |
" self.last = last\n", | |
" \n", | |
" @lazy_property\n", | |
" def fullname(self):\n", | |
" print \"fulname called\"\n", | |
" return self.first + \" \" + self.last\n", | |
"\n", | |
"p = Person(\"Foo\", \"Bar\")\n", | |
"print Person.fullname\n", | |
"print p.__dict__\n", | |
"print p.fullname\n", | |
"print p.__dict__\n", | |
"print p.fullname \n", | |
"\n", | |
"#p = Person(\"Foo\", \"Bar2\")\n", | |
"#print p.fullname" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"<__main__.lazy_property object at 0x102f7c1d0>\n", | |
"{'last': 'Bar', 'first': 'Foo'}\n", | |
"fulname called\n", | |
"Foo Bar\n", | |
"{'fullname': 'Foo Bar', 'last': 'Bar', 'first': 'Foo'}\n", | |
"Foo Bar\n" | |
] | |
} | |
], | |
"prompt_number": 111 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## `__slots__`" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class Point(object):\n", | |
" def __init__(self, x, y):\n", | |
" self.x = x\n", | |
" self.y = y" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 112 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"p = Point(1, 2)\n", | |
"p.__dict__" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "pyout", | |
"prompt_number": 113, | |
"text": [ | |
"{'x': 1, 'y': 2}" | |
] | |
} | |
], | |
"prompt_number": 113 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class Point2(object):\n", | |
" __slots__ = [\"x\", \"y\"]\n", | |
" def __init__(self, x, y):\n", | |
" self.x = x\n", | |
" self.y = y\n", | |
"\n", | |
"p2 = Point2(1, 2)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 115 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"p2.__dict__" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"ename": "AttributeError", | |
"evalue": "'Point2' object has no attribute '__dict__'", | |
"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-116-6207db46af2a>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mp2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__dict__\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", | |
"\u001b[0;31mAttributeError\u001b[0m: 'Point2' object has no attribute '__dict__'" | |
] | |
} | |
], | |
"prompt_number": 116 | |
}, | |
{ | |
"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