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))