您的位置:首页 > 编程语言 > Python开发

python入门3

2015-10-27 11:14 453 查看
python 比较6的

函数式编程

**:首先 先要知道 变量可以指向函数,然后这个变量就是函数了,就可以当做函数被使用。

高阶函数

*:函数的参数可以接收变量,也可以接收 函数,凡是接收函数的函数,叫做高阶函数

例1:def add(x,y,f):

return f(x)+f(y)
add(10,5,abs)
例2 : import math
def add(x, y, f):
return f(x) + f(y)
print add(25, 9, math.sqrt)
**


map()

**高阶函数:接收一个函数f和一个list;返回一个新的list(原来的list中每一个element都被f操作一遍)

例 def f(x):
return x*x
return map(f,[1,2,3,4,5])


reduce()

高阶函数:同样接收一个f和list,与map不同,f(x,y)必须接收两个参数

f将list中每2个element一次操作一遍,,先操作第一个和第二个,然后操作结果,与第三个操作,还可以设置个初始值reduce(f,list,num)使list中第一个数先和num操作然后结果与第二个操作

例子 def f(x,y)
return x+y
reduce(f,[1,2,3,4,5],100)
## #
## ##


filter() ##

高阶函数:同样接收一个f和list,f对每一个元素进行判断 返回的 true 或者false 根据结果 筛掉不符合的元素

例子1 def is_odd(x):
return x % 2 == 1
然后,利用filter()过滤掉偶数:
filter(is_odd, [1, 4, 6, 7, 9, 12, 17])

例子2  def is_not_empty(s):
return s and len(s.strip()) > 0
filter(is_not_empty, ['test', None, '', 'str', '  ', 'END'])


sorted(f,list)

高阶函数:用来排序

f(x,y)

想要让x在y前面 return -1

x在y后面 return 1

x和y相等 return 0

例子1

def reversed_cmp(x, y):
if x > y:
return -1
if x < y:
return 1
return 0
sorted([1,2,3,6,3,7],f)
例子2
def cmp_ignore_case(s1, s2):
u1 = s1.upper()
u2 = s2.upper()
if u1 < u2:
return -1
if u1 > u2:
return 1
return 0
print sorted(['bob', 'about', 'Zoo', 'Credit'], cmp_ignore_case)


返回函数 ##

函数不光能接收函数,还能返回函数,

def calc_sum(lst):
def lazy_sum():
return sum(lst)
return lazy_sum
calc_sum 返回的是lazy_sum
print calc_sum([1,2,3,4,5,6])


我们会发现打印的是个lazy_sum函数地址而不是结果

如果想执行结果

我们需要 执行 返回的函数;

f=calc_sum([1,2,3,4,5,6])

print f(),其应用可以让结果不立即出来,

看下一个内容 闭包

闭包

讲函数定义到函数里面,目的是使里面的函数(内函数)不被外面访问,

但是当内函数用到外函数的变量作为参数的时候 ,我们成为闭包。

切记一定不要用 外面函数中变化的 变量来作为参数如

例:def outer():
fs[]
for i in range(1,4)
def inner():
fs.append i*i
return i*i
return fs
f1,f2,f3= outer()
print f1(),f2(),f3()
返回结果为 9,9,9
(这里用三个函数接收因为fs存的是三个方法而不是值)
不信你自己print fs或者累不下面的代码
def count():
fs = []
for i in range(1, 4):
fs.append(i*i)
return fs

f=count()
print f
如果你不想返回三个9 那么 找一个先的参数接收
def count():
fs=[]
for i in range(1,4)
def f(y):
def lo():
y=i
return y*y
return lo
fs.append(f(i))
return fs
就会返回1,4,9
def f(y):
def lo():
y=i
return y*
return lo


注意这个

其实返回的是[f1(),f2(),f3()]

期间我看的是廖雪峰的教程,想法有些抽象。慢慢看半天就差不多了

匿名函数

python对匿名函数有一些支持,单只支持单行的表达式格式是

lambda: 参数 单行函数

匿名函数有个限制,就是只能有一个表达式,不写return,返回值就是该表达式的结果。

例sorted([1,2,3,4,5],lamdba x,y:  -cmp(x,y))
[5,4,3,2,1]
map(lamdba x:x*x,[1,2,3,4,5])


装饰器

类似于java 中的拦截器,不过python能非常轻松的完成,而且功能更加强大,如:给一个函数 日志,用高阶函数完成

def pre(f):
def g():
print 'call%s '%(f.__name__)
r=f()
return r
return g
然后用
l=pre(f)---->f=pre(f)去调用
python中省去了调用 直接写
@pre(f)


即可写日志!
**无参装饰器**:   装饰器要装饰不同函数,当函数参数不同,如果装饰器将 参数写固定, 就会出现编译错误
这时要借助 *args **kw将参数写可变
例子:同上,写日志:


def pre(f):
def fn(*args,**kw):
print 'call %s '%(f.__name__)
return f(*args,**kw)
return  fn
import time
例子:在函数上打印使用时间
def performance(f):
def fn(*args,**kw):
t1=time.time()
r=f(*args,**kw)
t2=time.time()
print 'call %s() in %fs'%(f.__name__,(t2-t1))
return r
return fn
@performance
def factorial(n):
return reduce(lambda x,y: x*y, range(1, n+1))
print factorial(10)


用参装饰器 ##

当你想写的日志不是固定的call f.name, 想针对不同的函数设置不同的级别 这时候需要给装饰器更完善一下

def log(index):
def wraps(f):
def g(*args,**kw):
print'[%s]call %s '%{index,f.__name__}
return f(*args,**fw)
return g
return wrap
@log
fercial()
打印调用函数所用时间
import time

def performance(unit):
def pre_decorator(f):
def log(*args,**kw):
time1 =time.time()
r=f(*args,**kw)
time2 = time.time()
if unit =='ms':
t=(time2-time1)*1000
else:
t=(time2-time1)
print 'call %s() in %f %s'%(f.__name__,t,unit)
return r
return log
return pre_decorator

@performance('s')
def factorial(n):
return reduce(lambda x,y: x*y, range(1, n+1))


print factorial(10)

进一步优化装饰器

当再使用装饰器的时候打印的name,doc都是装饰器里的属性

有一些依靠name来操作的函数就会出现错误,为了避免

应该使装饰器里的函数的name,doc等于被装饰函数

def perform(f):
def wraps(*args,**kw):
wraps.__name__=f.__name__
wraps.__doc__=f.__doc__
return f(*args,**kw)
return  wraps
@perform
def fercial(n):
print n
print fercial.__name__
python有个简单的:functools中的wraps方法
import functools
def log(f):
@functools.wraps(f)
def wrapper(*args, **kw):
print 'call...'
return f(*args, **kw)
return wrapper


偏函数

当一个函数有很多参数时,调用者就需要提供多个参数。如果减少参数个数,就可以简化调用者的负担。

比如,int()函数可以把字符串转换为整数,当仅传入字符串时,int()函数默认按十进制转换:

int(‘12345’)

12345

但int()函数还提供额外的base参数,默认值为10。如果传入base参数,就可以做 N 进制的转换:

int(‘12345’, base=8)

5349

int(‘12345’, 16)

74565

假设要转换大量的二进制字符串,每次都传入int(x, base=2)非常麻烦,于是,我们想到,可以定义一个int2()的函数,默认把base=2传进去:

def int2(x, base=2):

return int(x, base)

这样,我们转换二进制就非常方便了:

int2(‘1000000’)

64

int2(‘1010101’)

85

functools.partial就是帮助我们创建一个偏函数的,不需要我们自己定义int2(),可以直接使用下面的代码创建一个新的函数int2:

import functools

int2 = functools.partial(int, base=2)

int2(‘1000000’)

64

int2(‘1010101’)

85

所以,functools.partial可以把一个参数多的函数变成一个参数少的新函数,少的参数需要在创建时指定默认值,这样,新函数调用的难度就降低了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python