十五、python class 类学习笔记
来源:互联网 发布:搪瓷 知乎 编辑:程序博客网 时间:2024/05/18 13:08
# problem 1class Foo: x = 1f1 = Foo()f2 = Foo()print Foo.x, f1.x, f2.xf2.x = 2print Foo.x, f1.x, f2.xFoo.x = 3print Foo.x, f1.x, f2.x
# problem 4class A: x = 1 def f(self): return self.xclass B(A): x = 2 def g(self): return self.xa = A()b = B()print a.f()print b.f(), b.g()
# problem 7x = 1class Foo: a = x x = 2 print a, xprint x
Example: Timer class
Problem: Write a Timer
class.
class Timer: passdef timepass(): for i in range(10000): for j in range(1000): x = i*jt = Timer()t.start()timepass()t.stop()print "took %f seconds" % t.elapsed
Ducktyping
%%file numbers.txtonetwothreefourfive
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, ccprint 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): passprint wordcount(FakeFile())class Foo: passf = Foo()f.read = lambda: ""f.readlines = lambda: []f.seek = lambda n: 0print wordcount(f)
Problem: Write a class UpperCaseFile
, that takes a fileobj as argument and behaves like a file, but returns everything in uppercase when read.
f = UpperCaseFile(open("numbers.txt"))line = f.readline() # should give "ONE\n"lines = f.readlines() # should give ["TWO\n", "THREE\n", "FOUR\n", "FIVE\n"]f = UpperCaseFile(open("numbers.txt"))print wordcount(f) # should be same as wordcount(open("numbers.txt"))
There is a StringIO
class in StringIO
module that give file like interface to in-memory object.
from StringIO import StringIOf = StringIO()f.write("hello\nworld\n")f.seek(0)print f.read()f.seek(0)print wordcount(f)
Special Class Methods
x = 1print 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)
We need to implement __repr__
to fix that.
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]
Emulating Container Types
# 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__()
Example: yrange
Lets write a class yrange
that behaves like built-in class xrange
.
Example: Node
class
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 + indexy = yrange(2, 8)print len(y)print y[3]
Problem: Implement a Node class that allows accessing properties like a dictionary.
class Node: def __init__(self, tagname, **attrs): self.tagname = tagnamex = Node("input", type='text', name='x', id='id_x')x['class'] = 'required'x['value'] = 'foo'print x['name'], x['value']print x
## Command library using classes
%%file command1.pyclass 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.pyfrom command1 import Commandclass 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.pyfrom command1 import Commandclass 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
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.
python replace.py def define grep2.py command1.py
Lets try to improve the Command
class to handle to make it more generic.
%%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
Understanding Methods
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 adderadd5 = 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 ff = bindself(Foo.getx, foo)f()
Looking inside objects
class Foo: x = 1 def getx(self): return self.xfoo = Foo()
Foo
dir(Foo)
Foo.__dict__
Foo.__dict__['x'] = 2Foo.x
Foo.__dict__['y'] = 3Foo.y
# Lets try to find how add5 is storing value of xdir(add5)
def inc(x, amount=1): return x+amount
inc.func_defaults
How Python stores variables?
x = 1 # what does this mean?
g = globals()
g['x']
g['x'] = 2
x
Understanding Function Calls
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)
Problem: Write timeit
decorator as a class.
class timeit: ....@timeitdef timepass(): for i in range(10000): for j in range(1000): x = i*j
Understanding Atributes
class Foo(object): x = 1foo = Foo()
foo.x = 1foo.x
getattr(foo, "x")
class Attr: def __getattr__(self, name): return name.upper()
a = Attr()a.x
a.y
a.foo
getattr(a, "x")
Old-Style vs. New-Style Classes
x = 1type(x)
type(int)
class Foo: pass
type(Foo)
type(file)
class Foo(object): passtype(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 4bar = 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]
Properties
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.fullnameprint p.phonep.phone = "1234567890"print p.phone
dir(Person)
Person.phone
p.phone
p.firstname
p.__dict__
Person.__dict__
Person.phone.__get__(p)
Person.phone is a property object, but p.phone gives us a string value instead of a property.
class SimpleDescriptor(object): def __get__(self, obj, type=None): if obj is None: return self else: return 1class Foo: x = SimpleDescriptor()
Foo.x
foo = Foo()foo.x
Lets try to implement property class.
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.fullnameprint p.fullnameprint 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.lastp = Person("Foo", "Bar")print Person.fullnameprint p.__dict__print p.fullnameprint p.__dict__print p.fullname #p = Person("Foo", "Bar2")#print p.fullname
__slots__
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 = yp2 = Point2(1, 2)
p2.__dict__
- 十五、python class 类学习笔记
- Python学习笔记(十五):类基础
- python类class学习笔记
- python 学习笔记(十五)
- python基础教程学习笔记十五
- Python 学习笔记:class
- Python学习笔记(十五)----Python字符串
- python学习笔记-10(类class)
- Python学习笔记:类(class)
- linux下python学习笔记(十五)
- python 学习笔记(二十五)
- python学习笔记(十五) - ORM框架(SQLAlchemy)
- Java菜鸟学习笔记--面向对象篇(十五):Wrapper Class包装类
- python学习笔记1---class
- 学习Python(十五)
- Python学习杂记十五
- Python学习十五:sorted()
- python 系统学习笔记(十五)---正则表达式
- 整数压缩算法
- Yii关联表字段查询
- 无领导小组讨论面试真题解析(三)
- WebService的开发、部署、调用
- Boost库之bind的使用
- 十五、python class 类学习笔记
- Python reduce函数
- diff和patch使用指南
- 谁偷了我的热更新?Mono,JIT,IOS
- Android Volley 之自定义Request
- 环境常用命令(windows & linux)
- ViewFlow 源码阅读笔记(1)
- openstack学习笔记---libvirt
- 在Ubuntu 14.04 64bit上使用Sphinx转换MonaServer项目文档