python学习第四天,列表生产式,匿名函数,生成器,内置函数,迭代器,装饰器,json和pickle的序列化和反序列化

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python学习第四天,列表生产式,匿名函数,生成器,内置函数,迭代器,装饰器,json和pickle的序列化和反序列化相关的知识,希望对你有一定的参考价值。

列表生成式,生产器

#列表生成式,可以是代码更复杂
a = [i for i in range(10)] #这里的i,可以使用函数来装饰
print(a)

#生产器:就是数据在调用的时候才有
b = (x*2 for x in range(1000))
#print(b[3]),直接调用会报错,因为数据还没有生产呢
b.__next__()
b.__next__()
b.__next__()
# print(b[1]),这也会报错,因为生成器只保持当前数据
print(b.__next__())#只能使用这样的方式取值
print((x*2 for x in range(10)))

#将一个函数编程一个生成器
#斐波那契数列
def feibo(max):
    n,a,b = 0 ,0,1
    while n < max :
        # print(b)
        yield b #这样就样这个函数变成一个生成器了,生成器只有__next__()方法
        a,b = b,a+b #这里的意思是,将b赋值给a,将 a+b的结果赋值给b(这里的a不是赋值后的a)
        #这句话的意思就是 t = tuple(b,a+b)
        n = n+1
    return "done"
# feibo(6)
f = feibo(6)
#这样就将 函数给挂起了,运行其他的逻辑,然后在返回,当取到最后一个在next就会报错,可以使用try except 来处理异常

try:
    while True:
        f.__next__()
except StopIteration as e:#将最后的返回值复制个e的这个异常对象中
    print(e.value)

#简单的一个生产消费者模型

def consume(name):
    print("%s is begin"%name)
    while True:
        a = yield
        print("%s 开始消费 %s"%(name,a))

def provide():
    #这里有两个消费者
    c1 = consume("zhang")
    c2 = consume("yu")
    c1.__next__()
    c2.__next__()
    for i in range(10):
        c1.send(i)#这就是讲i传给上面yield这个地方
        c2.send(i)
provide()

#什么是迭代器,被next方法的迭代对象就是迭代器,其中list,set都是可迭代对象,但是不是迭代器
#可以直接做用于 for循环的对象,就是迭代对象 可以使用
from collections import Iterable
#Iterator迭代器
from collections import Iterator
isinstance("abc",Iterable)

匿名函数,内置函数

#1.匿名函数,就是没有方法名的函数,使用 lamdba 关键字

a = lambda x:x+2
# lambda x:x+2 这就是一个匿名函数,x代表参数,x+2代表 函数体
print(a(3))
#2.内置函数
#1.abs()求绝对值
print(abs(-3.5))
all()#迭代器中所有的元素都为真,才是真
any()#迭代器中任何一个为真就是真
ascii()#将数字转为ascii对象的值
bin()#转为二进制
bool()#测试一个对象是正还是假
bytearray()#字节数组
callable()#是否可以调用
chr(),ord()#查看10进制对象的ascii/查看ascii对应的十进制
dir()#返回当前范围内的变量
globals(),locals()#全局属性,局部属性
zip()#将两个列表,1,1对应转为一个新的列表
b= zip([1,2,3],["a","b","c"])
for i in b:
    print(i)
from functools import reduce
a = reduce(lambda x,y:x+y,range(10))
print(a,type(a))
#过滤器,按照fun,条件进行过滤,这里可以直接使用匿名函数来简化代码
c  = filter(lambda x:x<5, [i for i in range(10)])
for i in c:
    print(i)
d = map(lambda x:x*2,[i for i in range(10)])
for i in d:
    print(i)
#讲map与reduce结合使用,求 1!+2!+3!+4!
#阶乘,这个是4的阶乘
factorial = reduce(lambda f,c:f+c,map(lambda a:reduce(lambda x,y:x*y,range(1,a+1)),range(1,5)))
print(factorial,type(factorial))
#排序
#将字典排序
info = {1:"a",5:"f",3:"c",2:"b",4:"d"}
#1.按key进行排序
print(sorted(info.items()))
#2.如果按value排序呢
print(sorted(info.items(),key = lambda x:x[1]))

装饰器:

#1.高阶函数,参数是函数,或者返回值是函数的
#嵌套函数,就是函数里面在定义函数
#可以讲函数,当成一个变量进行传递
#高阶函数+嵌套函数==装饰器
#装饰器的作用就是,不改变原函数,不改变函数的调用方式
import  time,pickle

#1.高阶函数 将函数作为参数传递
def deco1(func):#将函数当成一个变量传递过来,实际上是将函数的内存地址传递过来,函数名+()调用这个函数
    start_time = time.time()
    func()
    end_time = time.time()
    print("%s这个函数运行是时间%d"%(func,end_time-start_time))


#deco1(func)
#2.高阶函数 返回值为函数
def deco2(func):
    start_time = time.time()
    #这句话的意思就是将func这个函数的内存地址返回去
    return func
    end_time = time.time()
    print("%s这个函数运行是时间%d" % (func, end_time - start_time))

# func = deco2(func)
# func()
#3.嵌套函数,就是在函数里面定义函数
def deco3():
    def deco4():
        print("deco4..run")
    #函数就相当于一个变量,定义一个函数,就相当于在内存空间声明了一个内存地址
    #所以这个地方一定要调用,要不只是声明没有调用的地方
    deco4()
# deco3()


#如何对一个函数进行装饰,并且不改变函数的调用方式
#例如对func()进行装饰

#1.不改变函数的内部
def deco5(func):
    start_time = time.time()
    func()
    end_time = time.time()
    print("%s这个函数运行是时间%d" % (func, end_time - start_time))

#2.不改变函数的调用方式,(使用嵌套函数,再包一层,将包装后的函数返回)
def deco6(func):
    def waps():
        start_time = time.time()
        func()
        end_time = time.time()
        print("%s这个函数运行是时间%d" % (func, end_time - start_time))
    return waps
@deco6
def func():
    time.sleep(1)
    print("func运行")
#这个是调用:这样就实现的装饰
# func = deco6(func)#这句话,python直接使用 @装饰器名称表示
# func()
#如果函数带有参数怎么处理呢,就是在内部函数带参数来接受被装饰函数的参数

def deco7(func):
    def wrapper(name):
        start_time = time.time()
        func(name)
        end_time = time.time()
        print("%s这个函数%s运行是时间%d" % (func, name,end_time - start_time))
    return wrapper
@deco7
def func1(name):
    print("name",name)
func1("aa")
#如果func1有多个参数呢,所以使用可变参数来接受,最后修改为
def deco8(func):
    def wrapper(*args,**kwargs):
        start_time = time.time()
        func(*args,**kwargs)
        end_time = time.time()
        print("%s这个函数运行是时间%d" % (func, end_time - start_time))
    return wrapper

@deco8
def func2(name,age):
    time.sleep(1)

# func2("zhang",22)

#如果装饰器自己也需要参数,改如何处理呢
#例如
#home 和 account 这两个函数使用不同的登陆方式登陆的,如何使用一个装饰器满足所有需求
#这里使用了同一张验证方式,如果装饰器上传一个参数,代表这个方法不需要登陆该如何处理
def login(fun):
    def wrapper(*args,**kwargs):
        name = input("your namne")
        passwd = input("your password")
        if name == "zhang" and passwd == "123":
            fun(*args,**kwargs)
        else:
            print("登陆失败")
    return wrapper
def loginArg(type):
    def login(fun):
        def wrapper(*args,**kwargs):
            if type == "login" :
                name = input("your namne")
                passwd = input("your password")
                if name == "zhang" and passwd == "123":
                    fun(*args,**kwargs)
                else:
                    print("登陆失败")
            elif type == "nologin" :
                fun(*args, **kwargs)
        return wrapper
    return login


@loginArg(type="login")
def home(name):
    print("%s in home"%name)
#这个就不需要登陆
@loginArg(type="nologin")
def account(name):
    print("%s in account"%name)

json序列化和pickle序列化

#序列化和反序列化json,pickle
import json
#json的load 与dump是保存和加载 json格式的文件
info = {"name":"zhang","age":22,"addr":"china"}
info1 = [1,2,3,4,5,6,login]
#这种info1中保存了一个函数的内存地址
# print(info1)
with open("json","w") as f:
    # json.dump(info1,f)
    f.writelines(json.dumps(info))
#或者使用
    # f.writelines(json.dumps(info1))
    #这样在使用json就会报错,因为 function‘ is not JSON serializable
with open("json","r") as f:
    # json.loads()
    # aa = json.load(f)
    #可以写成
    aa = json.loads(f.read())
    print(type(aa))#可以看到,这样的aa的类型是 dict,如果是一帮的
#json是所有语言都有的共性的
#这里就使用pickle这个序列化,是python特有的个性的序列化
with open("pickle","wb") as f:
    pickle.dump(info1,f)
    #write() argument must be str, not bytes
    #这句话明显表示,pickle.dump(info1,f)这需要一个(所以,这里将文件的打开方式按照b形式打开)
    #或者写成
    # f.write(pickle.dumps(info1))

with open("pickle","rb") as f:
    # aa = pickle.load(f)
    aa = pickle.loads(f.read())
    print(type(aa),aa)
#这样就可以取出来了,但是这里有一个问题,因为列表中有一个函数,如果在另一个文件打开的话,这个函数会报错,所以需要对这个函数特殊处理

 

以上是关于python学习第四天,列表生产式,匿名函数,生成器,内置函数,迭代器,装饰器,json和pickle的序列化和反序列化的主要内容,如果未能解决你的问题,请参考以下文章

python学习第十四天 生成器函数进阶 生成器表达式 各种推导式

python学习之第四天

第四天 PYTHON 函数

Python基础-第四天

py3.0第四天 函数

生成式,匿名函数及内置函数部分使用方法