6.抽象
collable判断函数是否可调用
>>> import math
>>> x=1
>>> y=math.sqrt
>>> callable(x)
False
>>> callable(y)
True
>>> def square(x):
... 'x*x' #在函数开头写下字符串,它就会作为函数的一部分进行存储,即文档字符串。
... return x*x
...
>>> square.__doc__
'x*x'
>>> def test():
... print 'test'
... return #用于结束函数
... print 'end'
...
>>> test()
test
>>> def try_to_change(n):
... n="Mr.Gumby"
...
>>> name="Bob"
>>> try_to_change(name)
>>> name
'Bob'
>>> def change(n):
... n[0]="Mr.Gumby"
...
>>> x=["Bob"]
>>> change(x)
>>> x
['Mr.Gumby']
>>> x
['Mr.Gumby', 'Jobs']
>>> y=x[:]
>>> x==y
True
>>> x is y
False
>>> def print_params(title,*params):
... print title
... print params
...
>>> print_params('sdaf',1,2,3,4)
sdaf
(1, 2, 3, 4)
>>> print_params('nothing')
nothing
()
>>> def print_params2(x,y,z=3,*pospar,**keypar):
... print x,y,z
... print pospar
... print keypar #返回字典
...
>>> print_params2(1,2,3,5,6,7,foo=1,bar=2)
1 2 3
(5, 6, 7)
{'foo': 1, 'bar': 2}
>>> def add(x,y):
... return x+y
...
>>> params=(1,2)
>>> add(*params)
3
>>> x=1 #变量和所对应的值用的是不可见的字典,用内建vars函数可以返回这个字典。
>>> scope=vars()
>>> scope['x']
1
>>> x=1 #全局变量
>>> def change_global():
... global x
... x+=1
...
>>> change_global()
>>> x
2
>>># python函数可以嵌套,可用函数创建另一个函数。
>>> def multiplier(factor):
... def multiplyByFactor(number):
... return factor*number
... return multiplyByFactor
>>> double=multiplier(2)
>>> doulble(5)
10
>>># multiplyByFactor存储子封闭作用域的行为叫做闭包。
7.更加抽象
多态polymorphism:可以对不同类的对象使用同样的操作,并根据类型的不同表现出不同的行为。
封装encapsulation:对外部世界隐藏对象的工作细节。
继承inheritance:以通用的类为基础建立专门的类对象。
>>>#-------多态
>>> def add(x,y):
... return x+y
...
>>> add('a','b')
'ab'
>>>#-------封装
创建自己的类
>>> class Person:
... def setName(self,name):
... self.name=name
... def getName(self):
... return self.name
... def greet(self):
... print "Hi,I\'m %s." % self.name
...
>>> foo=Person()
>>> foo.setName("Alice")
>>> foo.getName()
'Alice'
>>> foo.greet()
Hi,I'm Alice.
>>>#---私有化
>>>#------让方法或特性变为私有(从外部无法访问),只要在名字前加双下划线。
>>> class Secretive:
... def __inaccessible(self):
... print "U can't see me."
... def accessible(self):
... print "the secret message :"
... self.__inaccessible()
...
>>> s=Secretive()
>>> s.__inaccessible()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: Secretive instance has no attribute '__inaccessible'
>>> s.accessible()
the secret message :
U can't see me.
类的命名空间
>>># 下两句等价
>>>def foo(x): return x*x
>>>foo=lambda x:x*x
>>># 所有class语句代码都在类命名空间里执行。
超类与继承
>>> class Filter:
... def init(self):
... self.blocked=[]
... def filter(self,sequence):
... return [x for x in sequence if x not in self.blocked]
...
>>> class SpamFilter(Filter): #可有多个超类,即多重继承 class foo(foo1,foo2):
... def init(self):
... self.blocked=['SPAM']
...
>>> s=SpamFilter()
>>> s.init()
>>> s.filter(['SPAM','SPAM','bacon'])
['bacon']
>>> issubclass(SpamFilter,Filter)
True
>>> SpamFilter.__bases__
(<class __main__.Filter at 0x00000000010786A8>,)
>>> isinstance(s,Filter) #Fileter的间接实例,SpamFilter的直接实例
True
>>> s.__class__
<class __main__.SpamFilter at 0x00000000010785E8>
>>> hasattr(s,'filter')
True
>>> callable(getattr(s,'filter',None))
True
查看对象存储的值,可用__dict__特性。
查看对象组成,可用inspect模块。
名词—类 动词----方法 形容词----特性
8.异常
python用异常对象exception object来表示异常情况。遇到错误会引发异常,如果异常对象未被处理或捕捉,程序就会用回溯traceback终止执行。事实上每个异常都是一些类(如ZeroDivisionError)的实例。
>>> raise Exception
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Exception
>>> raise Exception("hyperdrive overload")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Exception: hyperdrive overload
>>> import exceptions
>>> dir(exceptions)
# try/except语句
#try:
# except(error,error...),e:
# print e
>>> try:
... x=input("the first number:")
... y=input("the second number:")
... print x/y
... except ZeroDivisionError:
... print "the second number can't be zero"
...
the first number:1
the second number:0
the second number can't be zero
>>> try:
... x=input("the first number:")
... y=input("the second number:")
... print x/y
... except:
... print "something wrong happened..."
#这样全捕捉是危险的,因为会隐藏程序员未想到的错误。
>>> try:
... print "a simple task."
... except:
... print "something went wrong."
... else:
... print "it went as planned."
...
a simple task.
it went as planned.
#finally语句
>>> try:
... x=1/0
... finally:
... print "cleaning up..."
... del x
...
cleaning up...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ZeroDivisionError: integer division or modulo by zero
9.魔法方法、属性和迭代器
如果文件以__metaclass__=type开始,那么类就是新式的。
构造方法
>>> class foobar:
... def __init__(self,value):
... self.somevar=value
...
>>> f=foobar("I am foobar.")
>>> f.somevar
'I am foobar.'
>>> class Bird:
... def __init__(self):
... self.hungry=True
...
>>> class SongBird(Bird):
... def __init__(self):
... Bird.__init__(self)
...
重写
>>> class A:
... def Hello(self):
... print "hi,I am A."
...
>>> class B(A):
... pass
...
>>> a=A()
>>> b=B()
>>> a.Hello()
hi,I am A.
>>> b.Hello()
hi,I am A.
>>> class B(A):
... def Hello(self):
... print "Hi,I am B."
...
>>> b=B()
>>> b.Hello()
Hi,I am B.
super函数
>>> class Bird:
... def __init__(self):
... self.hungry=True
...
>>> class SongBird(Bird):
... def __init__(self):
... super(SongBird,self).__init__()
...
序列和映射是对象的集合
__len__(self)
__getitem__(self,key)
__setitem__(self,key,value)
__delitem__(self,key)
通过访问器定义的特性被称为属性。
property函数
>>> __metaclass__=type
>>> class Rectangle:
... def __init__(self):
... self.width=0
... self.height=0
... def setSize(self,size):
... self.width,self.height=size
... def getSize(self):
... return self.width,self.height
... size=property(getSize,setSize)
...
# 第三个参数是一个用于删除特性的方法
#第四个特性是一个文档字符串
静态方法 staticmethod类型的对象
类成员方法 classmethod类型的对象
装饰器:在方法或函数的上方列出@
>>> class MyClass:
... @staticmethod
... def smeth():
... print "this is a static method."
... #classmethod
... def cmeth(cls):
... print "this is a class method of",cls
...
其他方法
__getattribute__ (self,name)
__getattr__ (self,name)
__setattr__(self,name,value)
__delattr__ (self,name)
迭代器
__ iter__方法会返回一个迭代器,即具有next方法,调用该方法时迭代器会返回它的下一个值。
生成器:包含yield语句的函数。
生成器由两部分组成:生成器的函数,生成器的迭代器。
生成器的函数是def语句定义的,包含yield。
生成器的迭代器是函数返回的部分。
>>> nested=[[1,2],[3,4],[5]]
>>> def flatten(nested):
... for sublist in nested:
... for element in sublist:
... yield element
...
>>> flatten(nested)
<generator object flatten at 0x000000000107B6C0>
>>> list(flatten(nested))
[1, 2, 3, 4, 5]
#还有递归生成器,通用生成器,模拟生成器
生成器方法:
send:外部作用域访问生成器。
throw:在生成器内引发一个异常。
close:停止生成器。
10.自带电池
导入模块时会生成经过处理编译的pyc文件,python能够有效处理。如果稍后导入同一模块,python会导入pyc文件。
重新导入模块可以用reload函数,它带有一个参数(要重新新导入的模块),并返回该模块。python3已经去掉reload函数。
使用__name__变量可以告知模块本身是作为程序运行还是导入到其它程序。
>>> __name__
'__main__'
>>>if __name__=='__main__':
function();
为了组织好模块,可以将它们分组为包package,即模块所在的目录,他必须包含一个命名为__init__.py的文件(模块)。
#比如文件constants/__init__.py包含语句PI=3.14
>>>import constants
>>>print constants.PI
>>> import copy
>>> dir(copy) #模块包含内容
...
>>> [n for n in dir(copy) if not n.startswith('_')]
['Error', 'PyStringMap', 'copy', 'deepcopy', 'dispatch_table', 'error', 'name', 't', 'weakref']
>>> copy.__all__ #__all__变量定义了模块的共有接口public interface
['Error', 'copy', 'deepcopy']
>>># import * 默认导入模块中所有不以下划线开头的全局名称
>>> copy.__file__ #源代码路径
'E:\\python2\\lib\\copy.pyc'
>>> import webbrowser
>>> webbrowser.open("http://www.python.org")
True
#---------sys
#---------os
#---------fileinput
集合,堆和双端队列
>>> set(range(10)) #无须import sets
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> set([1,2,3,1,2,3]) #忽略副本
set([1, 2, 3])
>>> set(['a','b','c']) #顺序随意
set(['a', 'c', 'b'])
>>> a=set(['a','b','c'])
>>> b=set(['a','b','d'])
>>> a.union(b)
set(['a', 'c', 'b', 'd'])
>>> a
set(['a', 'c', 'b'])
>>> a|b
set(['a', 'c', 'b', 'd'])
>>> c=a&b
>>> c
set(['a', 'b'])
>>> c.issubset(a)
True
>>> c<=a
True
>>> c.issuperset(a)
False
>>> a.intersection(b)
set(['a', 'b'])
>>> a.difference(b)
set(['c'])
>>> a-b
set(['c'])
>>> a.symmetric_difference(b)
set(['c', 'd'])
>>> a^b
set(['c', 'd'])
# 集合可变,所以不能用作字典的键。本身只包含不可变(可散列的)值,所以不包含其它集合。
#frozenset代表不可变(可散列)的集合
#堆
>>> from heapq import *
>>> from random import shuffle
>>> data=range(10)
>>> shuffle(data)
>>> heap=[]
>>> for n in data:
... heappush(heap,n)
...
>>> heap
[0, 1, 2, 4, 3, 7, 5, 8, 9, 6] #堆属性:位于i位置上的元素>i/2位置处的元素。
>>> heappop(heap)
0
>>> heappop(heap)
1
>>> heappop(heap)
2
>>> heappop(heap)
3
>>> heappop(heap)
4
>>> heap=[5,8,0,3,6,7,9,1,4,2]
>>> heapify(heap)
>>> heap
[0, 1, 5, 3, 2, 7, 9, 8, 4, 6]
>>> heapreplace(heap,0.5) #推出最小元素,推入新元素
0
>>> heap
[0.5, 1, 5, 3, 2, 7, 9, 8, 4, 6]
双端队列
collections模块包括deque类型。
>>> from collections import deque
>>> q=deque(range(5))
>>> q.append(5)
>>> q.appendleft(6)
>>> q
deque([6, 0, 1, 2, 3, 4, 5])
>>> q.pop()
5
>>> q.rotate(3) #右移3位
>>> q
deque([2, 3, 4, 0, 1])
>>> q.rotate(-1)
>>> q
deque([3, 4, 0, 1, 2])
#--------time
>>> import time
>>> time.asctime() #转换位ascii码
'Fri Jan 26 09:39:42 2018'
>>> time.time() #从新纪元1970.1.1.00开始到现在的秒数
1516930947.082
>>> time.sleep(2)
#--------random 真随机可用os.urandom(),random.SustemRandom()
>>> import random
>>> random.random() # 0-1
0.8748203769079271
>>> random.getrandbits(3) #给定二进制位数
2L
>>> random.uniform(1,10) #给定范围
8.78104517871366
>>> random.randrange(1,11,4)
5
>>> random.randrange(1,11,4)
9
>>> random.choice([1,2,3,4,5])
4
>>> a=[1,2,3,4,5]
>>> random.shuffle(a)
>>> a
[5, 1, 4, 3, 2]
>>> random.sample(a,3)
[2, 4, 5]
#----------------shelve
#----------------re
其它:functools,difflib,hashlib,csv,timeit,datetime,itertools,logging,getopt,optparse,cmd
11.文件和流
f=open(r'...')
open()参数二:文件模式
值 | 描述 |
---|---|
‘r’ | 读模式 |
‘w’ | 写模式 |
'a’ | 追加模式 |
‘b’ | 二进制模式(可添加到其它模式) |
‘+’ | 读/写模式(可添加到其它模式) |
open()参数二:缓冲
值 | 描述 |
---|---|
0或False | 无缓冲,读写直接针对硬盘。 |
1或True | 有缓冲,内存代替硬盘,使用flush或close时才更新硬盘数据。 |
>1 | 缓冲区大小。 |
-1或任何负数 | 使用默认缓冲区大小。 |
完成操作时一定要调用close()。
try:
# Write data to the file.
finally:
file.close()
#or
with open(r'') as somefile:
do_something #语句结束后自动close。
文件方法:
read(),readline().readlines()
seek(offset[,whence]):offset为偏移量,whence默认是0,即文件开头,1则是当前位置,此时offset可负。
tell()返回当前文件的位置。