1. 程式人生 > >python學習第四天,列表生產式,匿名函數,生成器,內置函數,叠代器,裝飾器,json和pickle的序列化和反序列化

python學習第四天,列表生產式,匿名函數,生成器,內置函數,叠代器,裝飾器,json和pickle的序列化和反序列化

數據 其他 imp 函數名 fun pro serializa and cal

列表生成式,生產器

#列表生成式,可以是代碼更復雜
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的序列化和反序列化