python入门5函数式编程

yield 本身可以生成 一个生成器对象,在python3中执行__next__()

def genNum(x):
    y=0
    while y<=x:
        yield y
        y+=1
        
g1=genNum(10)
for i in g1:
    print(g1.__next__())


#序列化:在程序运行中,所有变量都是在内存中操作,当程序一旦执行完毕,结束退出,变量所占的内存就被操作系统回收了,

#因此我们需要将某些数据持久化存储到磁盘中,下次运行的时候从磁盘中读取相关变量
#将变量编程可以存储或传输的过程称之为序列化,在python中叫做picking,

#其他语言成为serialization,marshaling,flattening等等,反之成为反序列化,把变量内容从序列化的对象重新读取到内存中

import pickle
try:
    import cPickle as pickle  #针对python2的用户
except ImportError:
    import pickle


d=dict(name='sicong',age=29,score=80)
str=pickle.dumps(d)
print(str)             #序列化  以二进制方式存储


f=open('first.txt','wb')
pickle.dump(d,f)
f.close()


f=open('first.txt','rb')   #反序列化


d=pickle.load(f)
f.close()
print(d)
print('name is %s' %d['name'])
'''


'''
使用json实现序列化和反序列化,以易懂的编码方式序列化
'''

import json
d1=dict(name='sicong',age=22,score=90)
str=json.dumps(d1)
print(str)


'''
调用json的loads函数实现反序列化
'''
d2=json.loads(str)
print('d2=',d2)

匿名函数:用lambda来创建匿名函数其主体是一个表达式,而不是一个代码块,仅仅能在lambda表达式中封装有限的逻辑进去,
#拥有自己的命名空间,且不能访问自有参数列表之外或者全局命名空间的参数
#虽然lambda函数看起来智能写一行,但是与c的内联函数有区别,后者的母的是调用小函数时不占用栈的内存从而增加运行效率

一个栗子:::

sum=lambda arg1,arg2:arg1+arg2
print(sum(10,20))
'''
辅助工具
reduce:是一个二元操作函数,他用来将一个数据集合(列表,元祖)中的所有数据进行如下操作:
传给reduce中的函数func()(必须是一个二元操作函数),现对集合中的第1,2个数据进行操作,
得到的结果再与第三个数据用func()函数运算,最后得到一个结果
顾名思义,reduce就是要把一个list给缩成一个值


from functools import reduce
ll=[1,2,3,4]
print(reduce(lambda arg1,arg2:arg1+arg2,ll))
#这里表示,把ll中的值一个个的放进lambda的arg1,arg2中
#还可以自己设置初始值,比如设置第一个值为5,第二个值为ll中的1
print(reduce(lambda arg1,arg2:arg1+arg2,ll,5))


map:map函数应用与每一个可以迭代的项,返回的是一个结果list,如果有其他的可迭代参数传进来,
map函数则会吧每一个参数都以相应的处理函数进行迭代处理,map()函数有两个参数,一个是函数,一个是序列
map函数将传入的依次作用到序列中的每一个元素,并把结果作为新的list返回
格式:map(func,seq1[,seq2,...])
map函数可以使用任何的lambda函数操作,本质是吧原有的一个列表根据lambda变为另一个列表list
l1=[1,2,3]
new_list=map(lambda x:x+1,l1)
new_list1=list(map(lambda x:x+1,l1))
#注意这里在外面套了一个list,目的是将里面的值显示出来,否则得到map这个函数
#而不是里面的值,但是这种情况只针对python3,python2环境中不需要外加list
print(new_list)
print(new_list1)
#还可以将两个list中的值变为1个
l2=[4,5,6]
new_list2=list(map(lambda x,y:x+y,l1,l2))
print(new_list2)
'''
'''
filter():该函数可以对序列做过滤处理,既可以用一个自定的函数过滤一个序列,把序列的每一项传到自定义的过滤函数里处理
并且返回结果做过滤,最终一次性返回过滤后的结果,和map()函数类似,filter()也可以接受一个函数和一个序列。
和map不同,filter把传入的函数依次作用于每一个元素,然后根据返回值是TRUE还是false决定保留还是放弃该元素
语法:filter(func,seq)
l3=[23,22,44,55,66,77,78]
new_list3=list(filter(lambda x:x>50,l3))
print(new_list3)
'''

闭包:一个函数和它的环境变量合在一起,就构成了一个闭包(closure),内层函数作为外层函数的返回

def line_conf():
    b=15   #称b为line的环境变量
    c=2
    def line(x):
        return 2*x+b+c
    return line


b=5
my_line=line_conf()
my_line(5)
print(my_line(5))
print(my_line.__closure__)
print(my_line.__closure__[1].cell_contents)

装饰器:就是函数的包装,增强其他函数的功能,能实现函数代码重用,功能重用(不同环境),适用于不同的设计模式

其一般接收一个函数对象作为参数,使得其功能增加,是闭包的进一步使用。

简单例子
def hello(fn):
    def wrapper():
        print('hello,%s'%fn.__name__)
        fn()
        print('bye,%s'%fn.__name__)
    return wrapper


@hello
def foo():
    print('i am foo')
    
foo()


#out:
#hello,foo
#i am foo
#bye,foo


可以看到:
1,在函数foo前面有个@hello的’注解‘,hello就是我们前面定义的函数hello
2,在hello函数中,需要一个fn的参数(这就是用来做回调的函数)
3,在hello函数中反悔了一个inner函数wrapper,这个wrapper函数回调了传进来的fn,并在回调前后加了两条语句
所以本质上来讲,用@decorator来装饰某个函数时,其实就是做了下面这件事
@decorator
def func():
    pass
变成 func=decorator(func)
就是把一个函数传到另一个函数中,再调回给自己
hello(foo)返回了wrapper(),所以foo其实变成了wrapper的一个变量,而后面的foo()执行其实变成了wrapper()
同理我们可以搞多个decorator:
@decorator_one
@decorator_two
def func():
    pass
相当于 func=decorator_one(decorator_two(func))
还可以给decorator带参数
@decorator_two(arg1,arg2)
def func():
    pass
相当于 func=decorator(arg1,arg2)(func)
'''

def deco(func):
    def wrapper(x):
        print('this is a decotor')
        func(x)
        print('bybe')
    return wrapper


@deco
def show(x):
    print(x)


show('hello !!')

结果:

this is a decotor
hello !!
bybe

看一个网页编程的例子


def makeHtmlTag(tag,*args,**kwads):
    def real_decorator(fn):
        css_class=" class='{0}'".format(kwads["css_class"]) \
        if "css_class" in kwads else " "
        def wrapped(*args,**kwads):
            return "<"+tag+css_class+">"+fn(*args,**kwads)+"</"+tag+">"
        return wrapped
    return real_decorator
@makeHtmlTag(tag='b',css_class='bold_css')
@makeHtmlTag(tag='i',css_class='italic_css')
def hello():
    return "hello world"


print(hello())
                       
#用class类来实现
#以下程序显示回调过程
class Mydecorator(object):
    def __init__(self,fn):
        print("inside mydecoraotor.__init__()")
        self.fn=fn
    
    def __call__(self):
        self.fn()
        print("inside mydecorator.__call__()")
        
@Mydecorator
def aFunction():
    print("inside aFunction()")
    
print("Finish decorating aFunction()")


aFunction()
 
#根据此,修改网页编程case
class makeHtmlTagClass(object):
    def __init__(self,tag,css_class=""):
        self.__tag=tag
        self.__css_class=" class='{0}'".format(css_class) if css_class !="" else ""
        
    def __call__(self,fn):
        def wrapped(*args,**kwargs):
            return "<"+self.__tag+self.__css_class+">"+fn(*args,**kwargs)+"</"+self.__tag+">"
        return wrapped


@makeHtmlTagClass(tag='b',css_class='bold_css')
@makeHtmlTagClass(tag='i',css_class='italic_css')
def hello(name):
    return "hello.{}".format(name)


print(hello('baby'))
''' 


'''
装饰器的副作用
因为decorator的原因,我们原本的函数其实已经变成了一个叫做wrapped函数,比如你再次调用__name__的时候
他会告诉你,这是wrapped而不是foo或者hello
但是python的functools包中提供了一个叫做wrap的decorator来消除这样的副作用


from functools import wraps
def hello(fn):
    @wraps(fn)
    def wrappder():
        print("hello.{}".format(fn.__name__))
        fn()
        print("goodbye.{}".format(fn.__name__))
    return wrappder


@hello
def foo():
    print("i am foo")
    pass


foo()
print(foo.__name__)
print(foo.__doc__)        
''' 
#用装饰器来装饰斐波那契数列,提高计算效率,主要体现在对已经计算过的fib(1),fib(2),fib(3),fib(4)。。等
#存储起来,当计算某个fib(n)进行分裂需要用到之前已经计算过的,直接调用就行,不用在重新重头计算过


from functools import wraps
def memo(fn):
    cache={}
    miss=object()
    
    @wraps
    def wrappder(*args):
        result=cache.get(args,miss)
        if result is miss:
            result=fn(*args)
            cache[args]=result
        return result
    return wrappder


@memo
def fib(n):
    if n<2:
        return n
    return fib(n-1)+fib(n-2)

偏函数 partial function
又可以翻译为部分函数,意思就是可以只设置一部分的参数


print(int ('12345',base=8))  #八进制的12345转化为十进制 5349
print(int ('12345',base=16)) #16进制的12345转化为十进制 74565
'''
#假设要转换大量的二进制字符串,每次都舒服int(x,base=2)显得太麻烦,于是可以定义一个int2()的函数,默认吧base=2穿进去
#这样转换二进制就方便多了


import functools
int2=functools.partial(int,base=2)
a=int2('1000000')
print(a)
#所以简单来说functools.partial的作用就是把一个函数的某些参数固定住,返回一个新的函数
kw={'base':8}#创建偏函数时,实际上可以接受函数对象、*args、**kw这三种参数,其中**可以当做一个dict带入
b=int('12345',**kw)
print(b)
#继续同理,可以吧*当做list塞进来
max2=functools.partial(max,10)
print(max2(5,6,7))
#相当于
args=(10,5,6,7)#注意10 在最左边
print(max(*args))

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值