# problem 1 class Foo: x = 1 f1 = Foo() f2 = Foo() print Foo.x, f1.x, f2.x f2.x = 2 print Foo.x, f1.x, f2.x Foo.x = 3 print Foo.x, f1.x, f2.x # problem 4 class A: x = 1 def f(self): return self.x class B(A): x = 2 def g(self): return self.x a = A() b = B() print a.f() print b.f(), b.g() # problem 7 x = 1 class Foo: a = x x = 2 print a, x print x %%file numbers.txt one two three four five def wordcount(fileobj): lc = len(fileobj.readlines()) fileobj.seek(0) wc = len(fileobj.read().split()) fileobj.seek(0) cc = len(fileobj.read()) return lc, wc, cc print wordcount(open("numbers.txt")) class FakeFile: def read(self): return "one\ntwo\nthree\n" def readlines(self): return ["one\n", "two\n", "three\n"] def seek(self, pos): pass print wordcount(FakeFile()) class Foo: pass f = Foo() f.read = lambda: "" f.readlines = lambda: [] f.seek = lambda n: 0 print wordcount(f) from StringIO import StringIO f = StringIO() f.write("hello\nworld\n") f.seek(0) print f.read() f.seek(0) print wordcount(f) x = 1 print x class Point: def __init__(self, x, y): self.x = x self.y = y def __str__(self): return "(%s, %s)" % (self.x, self.y) p = Point(2, 3) print p print repr(1) print repr("hello") print "hello" [1, 2, "3, 4"] print p print [p] print repr(p) class Point: def __init__(self, x, y): self.x = x self.y = y def __str__(self): return "(%s, %s)" % (self.x, self.y) def __repr__(self): return "Point(%s, %s)" % (self.x, self.y) p = Point(2, 3) print p, [p, "hello", (2, 3), 5] # Do you know what happens when you do this? x = [1, 2, 3, 4] print x[1] x.__getitem__(1) x = xrange(2, 8) print len(x) print x[3] x.__len__() class yrange: def __init__(self, start, stop): self.start = start self.stop = stop def __len__(self): return self.stop - self.start def __getitem__(self, index): return self.start + index y = yrange(2, 8) print len(y) print y[3] ## Command library using classes %%file command1.py class Command: def run(self, filenames): lines = self.readfiles(filenames) lines = self.generate_output(lines) self.printlines(lines) def process_line(self, line): """All bases classes should implement this.""" raise NotImplementedError() def generate_output(self, lines): for line in lines: for outline in self.process_line(line): yield outline def readfiles(self, filenames): for f in filenames: for line in open(f): yield line def printlines(self, lines): for line in lines: print line.strip("\n") %%file uppercase1.py from command1 import Command class UpperCase(Command): def process_line(self, line): yield line.upper() if __name__ == "__main__": import sys cmd = UpperCase() cmd.run(sys.argv[1:]) !python uppercase1.py uppercase1.py %%file grep2.py from command1 import Command class Grep(Command): def __init__(self, pattern): self.pattern = pattern def process_line(self, line): if self.pattern in line: yield line if __name__ == "__main__": import sys cmd = Grep(sys.argv[1]) cmd.run(sys.argv[2:]) !python grep2.py def grep2.py %%file command2.py """A new approach to writing Command class. """ class Command: def run(self, filenames): for filename in filenames: self.process_file(filename) def process_file(self, filename): for line in open(filename): process_line(line) def process_line(self, line): """All bases classes should implement this.""" raise NotImplementedError() class UpperCase(Command): def process_line(self, line): print line.upper() class WordCount(Command): def process_file(self, filename): lc = len(open(filename).readlines()) wc = len(open(filename).read().split()) cc = len(open(filename).read()) print lc, wc, cc, filename cmd = WordCount() cmd.run(["command1.py", "command2.py"]) !python command2.py class Foo: x = 1 def getx(self): return self.x foo = Foo() print foo.getx() print Foo.getx(foo) Foo.getx foo.getx def add(x, y): return x+y def make_adder(x): def adder(y): return add(x, y) return adder add5 = make_adder(5) print add5(6) def bindself(method, self): """Returns a new function with self already bound""" def f(*a, **kw): return method(self, *a, **kw) return f f = bindself(Foo.getx, foo) f() class Foo: x = 1 def getx(self): return self.x foo = Foo() Foo dir(Foo) Foo.__dict__ Foo.__dict__['x'] = 2 Foo.x Foo.__dict__['y'] = 3 Foo.y # Lets try to find how add5 is storing value of x dir(add5) def inc(x, amount=1): return x+amount inc.func_defaults x = 1 # what does this mean? g = globals() g['x'] g['x'] = 2 x def add(x, y): return x+y add(5, 4) d = [1, 2, 3] d[2] Foo Foo() class Adder: def __init__(self, x): self.x = x def __call__(self, y): return add(self.x, y) add5 = Adder(5) print add5(6) class Foo(object): x = 1 foo = Foo() foo.x = 1 foo.x getattr(foo, "x") class Attr: def __getattr__(self, name): return name.upper() a = Attr() a.x a.y a.foo getattr(a, "x") x = 1 type(x) type(int) class Foo: pass type(Foo) type(file) class Foo(object): pass type(Foo) class Foo(object): def __len__(self): return 4 foo = Foo() len(foo) foo.__len__ = lambda: 5 len(foo) class Bar: def __len__(self): return 4 bar = Bar() len(bar) bar.__len__ = lambda: 5 len(bar) class Bar: x = 1 def getx(self): return self.x bar = Bar() print bar.getx() # What does this mean? bar.getx() # f = bar.getx # f() # What what does x[1] class Person(object): firstname = "Foo" lastname = "Bar" _phonenumber = "0" @property def fullname(self): return self.firstname + " " + self.lastname @property def phone(self): return self._phonenumber @phone.setter def phone(self, value): if len(value) != 10: raise ValueError("Invalid Phone number") self._phonenumber = value #phone = property(_get_phone, _set_phone) p = Person() print p.fullname print p.phone p.phone = "1234567890" print p.phone dir(Person) Person.phone p.phone p.firstname p.__dict__ Person.__dict__ Person.phone.__get__(p) class SimpleDescriptor(object): def __get__(self, obj, type=None): if obj is None: return self else: return 1 class Foo: x = SimpleDescriptor() Foo.x foo = Foo() foo.x class my_property(object): def __init__(self, getter): self.getter = getter def __get__(self, obj, type=None): if obj is None: return self else: return self.getter(obj) class Person: @my_property def fullname(self): print "fulname called" return "Foo Bar" p = Person() print Person.fullname print p.fullname print p.fullname class lazy_property(object): def __init__(self, getter): self.getter = getter def __get__(self, obj, type=None): if obj is None: return self value = self.getter(obj) obj.__dict__[self.getter.__name__] = value return value class Person: def __init__(self, first, last): self.first = first self.last = last @lazy_property def fullname(self): print "fulname called" return self.first + " " + self.last p = Person("Foo", "Bar") print Person.fullname print p.__dict__ print p.fullname print p.__dict__ print p.fullname #p = Person("Foo", "Bar2") #print p.fullname class Point(object): def __init__(self, x, y): self.x = x self.y = y p = Point(1, 2) p.__dict__ class Point2(object): __slots__ = ["x", "y"] def __init__(self, x, y): self.x = x self.y = y p2 = Point2(1, 2) p2.__dict__