Skip to content

Instantly share code, notes, and snippets.

@anandology
Last active December 17, 2015 17:49
Show Gist options
  • Save anandology/5648714 to your computer and use it in GitHub Desktop.
Save anandology/5648714 to your computer and use it in GitHub Desktop.
Notes from Advanced Python workshop
Display the source blob
Display the rendered blob
Raw
{
"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