python入门3

python 比较6的

函数式编程

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


高阶函数

*:函数的参数可以接收变量,也可以接收 函数,凡是接收函数的函数,叫做高阶函数
例1:def add(x,y,f):

           return f(x)+f(y)
       add(10,5,abs)
 例2import 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()
        返回结果为 999
(这里用三个函数接收因为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 logindex):
    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可以把一个参数多的函数变成一个参数少的新函数,少的参数需要在创建时指定默认值,这样,新函数调用的难度就降低了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值