1、函数名是指向函数对象的变量,变量可以指向函数
2、高阶函数:能接受函数做参数的函数,把传过来的函数对象作为变量接收
3、常用函数:
map(f, L) | 接收一个函数和一个List,对每个元素执行函数,得到一个新的List |
reduce(f, L) | 接收一个函数(两个参数)和一个List,先对前两个执行函数,再对得到的结果和第三个执行函数......,使用前需 import functools 使用时 functools.reduce(f, L) |
filter(f, L) | 接收一个判断函数和一个List,对每个元素执行函数判断,返回true/false,对List过滤 |
sorted(L,f) | 只接收一个函数时对List升序排序,接受List和函数时按函数返回结果排序: -1:a排在b前面, 0:ab位置不变, 1:a排在b的后面,第二个参数为key = f()时按f()返回值排序 |
4、匿名函数:lambda x: -x if x < 0 else x 匿名函数可以简化函数的定义和使用,冒号前面是参数,冒号后面是返回值
5、装饰器decorator:接受一个函数,让这个函数在不做任何代码变动的情况下增加额外功能,返回值也是一个函数对象
@ 语法可以代替 f = decorate(f) 写法:
import time
import functools
def log(f):
def new_f(x):
print ('call '+f.__name__+'() in ', time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
return f(x)
return new_f
@log
def factorial(n):
return functools.reduce(lambda x,y: x*y, range(1, n+1))
print ('10的阶乘:', factorial(10))
6、带参数修饰器 decorator:在 @ 修饰里传入参数,定义修饰器时外加一层函数接收参数,返回修饰函数
import functools
def log(s):
def ff(f):
def fn(x):
print ('call '+f.__name__+'() in ',s)
return (f(x))
return (fn)
return (ff)
@log('csdn')
def factorial(n):
return functools.reduce(lambda x,y: x*y, range(1, n+1))
print ('10的阶乘:', factorial(10))
7、当函数被修饰后,原函数的属性不属于新函数,@functools.wraps(f) 可以将原函数属性复制到新函数:
import functools
def log(f):
@functools.wraps(f)
def wrapper(*args, **kw):
print 'call...'
return f(*args, **kw)
return wrapper
8、模块: 把代码写在不同 .py 文件中
9、包: 把模块放在不同包中,包就是文件夹,文件夹中必须有 __init__.py 文件,即使文件是空的
10、引用其他包中的模块:import p1.unil
11、使用模块中的变量和函数:p1.unil.a p1.unil.f(1, 2)
12、不完全引用:from math import pow, sin, log 可以直接使用::pow(2, 10) sin(3.14)
13、函数名冲突时可以起别名: from math import log as logger
14、动态导入模块:
try:
from cStringIO import StringIO
except ImporErrpr:
from StringIO import StringIO
try 的作用是捕获错误,并在捕获到指定错误时执行 expect 语句
15、面向对象编程:
class Person(object): #类名首字母大写
name = '' #类属性
__grade = 0 #访问限制, 私有属性
count = 0
def __init__(self,name,grade) #初始化:在创建对象时执行,第一个参数必须为self
self.name = name
self.grade = grade
Person.count = Person.count+1
def get_grade(self): #定义实例方法, 实例方法第一个参数 self 是实例本身
return self.grade
@classmethod #标记@classmethod把方法绑定到类上, 而不是实例
def how_many(cls): #定义类方法, 传入cls是类本身
return cls.count
# 访问类属性: Person.grade
# 修改类属性: Person.grade = 90
# 动态添加类属性: Person.adress = 'China'
# 访问类方法: Person.count
# 创建实例: p1 = Person('ming', 'm', 99) # 创建时提供 self 以外的初始化参数
# 访问实例属性: p1.name
# 修改实例属性: p1.name = 'John'
# 动态添加实例属性: p1.adress = 'China'
# 访问实例方法: p1.get_grade() # 传参时不需要传 self
16、继承一个类:
class Student(Person): #定义一个Student类, 继承Person类
def __init__(self, name, gender, score):
super(Student, self).__init__(name, gender) #继承父类,self参数已在super()中传入,不需要在__init__里写
self.score = score
17、多重继承:多重继承的目的是从两种继承树中分别选择并继承出子类,以便组合功能使用
18、多态:子类拥有自己的方法以及父类的方法,调用时优先查找自身的定义,如果没有定义,顺着继承链向上查找, 直到在某个父类中找到为止
19、type(123) 函数获取变量的类型,返回一个 Type 对象:<type 'int'>
20、isinstance(5,int) 可以判断一个变量的类型,返回 ture/false,既可以用在Python内置的数据类型如 str, list, dict,也可以用在我们自定义的类,它们本质上都是数据类型
21、dir(2) 获取变量的所有属性 ['__class__','__init__', '__setattr__', '__sizeof__', '__str__', 'name', 'score'......]
22、getattr(s, 'name') 获取对象属性: 'Jhon'
23、setattr(s, 'name', 'Tom') 设置对象属性
24、特殊方法:任何数据类型的实例都有一个特殊方法,双下划线开头双下划线结尾,如 __str__(),特殊方法定义在class中,不需要直接调用,某些函数或操作符会调用对应的特殊方法 print list # print list.__str__()
25、print list # print list.__str__() 某些函数或操作符会调用对应的特殊方法
class Fib(object):
def __init__(self, num):
self.num =num
self.L = [0, 1]
for i in range(0, num-2):
self.L.append(self.L[-2]+self.L[-1])
def __str__(self):
return str(self.L)
__repr__ = __str__
def __len__(self):
return len(self.L)
f = Fib(10)
print (f)
print (len(f))
26、定义类:有理数可以用一个 Rational 类来表示
class Rational(object):
def __init__(self, p, q):
self.p = p
self.q = q #p、q 都是整数,表示有理数 p/q
四则运算需要正确实现 __add__、__sub__、__mul__、__div__
class Rational(object):
def __init__(self, p, q):
self.p = p
self.q = q
def __add__(self, r):
return Rational(self.p * r.q + self.q * r.p, self.q * r.q)
def __sub__(self, r):
return Rational(self.p * r.q - self.q * r.p, self.q * r.q)
def __mul__(self, r):
return Rational(self.p * r.p, self.q * r.q)
def __div__(self, r):
return Rational(self.p * r.q, self.q * r.p)
def __str__(self):
if self.p < self.q:
k = self.p
else:
k = self.q
for x in range(k, 0, -1):
if self.p%x==0 and self.q%x == 0:
self.p = self.p / x
self.q = self.q / x
break
return '%s/%s' % (self.p, self.q)
__repr__ = __str__
r1 = Rational(1, 2)
r2 = Rational(1, 4)
print r1 + r2
print r1 - r2
print r1 * r2
print r1 / r2
27、Python是动态语言,任何实例在运行期都可以动态地添加属性
28、__slots__ 限制当前类所能拥有的属性 , __slots__ 是指一个类允许的属性列表
例如,Student 类只允许添加 name、gender 和 score 这3个属性:
class Student(object):
__slots__ = ('name', 'gender', 'score')
def __init__(self, name, gender, score):
self.name = name
self.gender = gender
self.score = score