一 函數是第一類對象,即函數能夠看成數據傳遞python
#1 能夠被引用 #2 能夠看成參數傳遞 #3 返回值能夠是函數 #3 能夠看成容器類型的元素
二 利用該特性,優雅的取代多分支的ifmysql
def foo(): print('foo') def bar(): print('bar') dic={ 'foo':foo, 'bar':bar, } while True: choice=input('>>: ').strip() if choice in dic: dic[choice]()
一 函數的嵌套調用linux
def max(x,y): return x if x > y else y def max4(a,b,c,d): res1=max(a,b) res2=max(res1,c) res3=max(res2,d) return res3 print(max4(1,2,3,4))
二 函數的嵌套定義git
def f1(): def f2(): def f3(): print('from f3') f3() f2() f1() f3() #報錯,爲什麼?請看下一小節
一 什麼是名稱空間?redis
#名稱空間:存放名字的地方,三種名稱空間,(以前遺留的問題x=1,1存放於內存中,那名字x存放在哪裏呢?名稱空間正是存放名字x與1綁定關係的地方)
二 名稱空間的加載順序sql
python test.py #一、python解釋器先啓動,於是首先加載的是:內置名稱空間 #二、執行test.py文件,而後以文件爲基礎,加載全局名稱空間 #三、在執行文件的過程當中若是調用函數,則臨時產生局部名稱空間
三 名字的查找順序express
局部名稱空間--->全局名稱空間--->內置名稱空間 #須要注意的是:在全局沒法查看局部的,在局部能夠查看全局的,以下示例 # max=1 def f1(): # max=2 def f2(): # max=3 print(max) f2() f1() print(max)
四 做用域編程
#一、做用域即範圍 - 全局範圍(內置名稱空間與全局名稱空間屬於該範圍):全局存活,全局有效 - 局部範圍(局部名稱空間屬於該範圍):臨時存活,局部有效 #二、做用域關係是在函數定義階段就已經固定的,與函數的調用位置無關,以下 x=1 def f1(): def f2(): print(x) return f2 x=100 def f3(func): x=2 func() x=10000 f3(f1()) #三、查看做用域:globals(),locals() LEGB 表明名字查找順序: locals -> enclosing function -> globals -> __builtins__ locals 是函數內的名字空間,包括局部變量和形參 enclosing 外部嵌套函數的名字空間(閉包中常見) globals 全局變量,函數定義所在模塊的名字空間 builtins 內置模塊的名字空間
五 global與nonlocal關鍵字json
一 什麼是閉包?緩存
#內部函數包含對外部做用域而非全局做用域的引用 #提示:以前咱們都是經過參數將外部的值傳給函數,閉包提供了另一種思路,包起來嘍,包起呦,包起來哇 def counter(): n=0 def incr(): nonlocal n x=n n+=1 return x return incr c=counter() print(c()) print(c()) print(c()) print(c.__closure__[0].cell_contents) #查看閉包的元素
二 閉包的意義與應用
#閉包的意義:返回的函數對象,不只僅是一個函數對象,在該函數外還包裹了一層做用域,這使得,該函數不管在何處調用,優先使用本身外層包裹的做用域 #應用領域:延遲計算(原來咱們是傳參,如今咱們是包起來) from urllib.request import urlopen def index(url): def get(): return urlopen(url).read() return get baidu=index('http://www.baidu.com') print(baidu().decode('utf-8'))
一 爲什麼要用裝飾器
#開放封閉原則:對修改封閉,對擴展開放
二 什麼是裝飾器
裝飾器他人的器具,自己能夠是任意可調用對象,被裝飾者也能夠是任意可調用對象。 強調裝飾器的原則:1 不修改被裝飾對象的源代碼 2 不修改被裝飾對象的調用方式 裝飾器的目標:在遵循1和2的前提下,爲被裝飾對象添加上新功能
三 裝飾器的使用
import time def timmer(func): def wrapper(*args,**kwargs): start_time=time.time() res=func(*args,**kwargs) stop_time=time.time() print('run time is %s' %(stop_time-start_time)) return res return wrapper @timmer def foo(): time.sleep(3) print('from foo') foo() 無參裝飾器
def auth(driver='file'): def auth2(func): def wrapper(*args,**kwargs): name=input("user: ") pwd=input("pwd: ") if driver == 'file': if name == 'egon' and pwd == '123': print('login successful') res=func(*args,**kwargs) return res elif driver == 'ldap': print('ldap') return wrapper return auth2 @auth(driver='file') def foo(name): print(name) foo('egon') 有參裝飾器
四 裝飾器語法
被裝飾函數的正上方,單獨一行 @deco1 @deco2 @deco3 def foo(): pass foo=deco1(deco2(deco3(foo)))
五 裝飾器補充:wraps
from functools import wraps def deco(func): @wraps(func) #加在最內層函數正上方 def wrapper(*args,**kwargs): return func(*args,**kwargs) return wrapper @deco def index(): '''哈哈哈哈''' print('from index') print(index.__doc__)
六 練習
一:編寫函數,(函數執行的時間是隨機的)
二:編寫裝飾器,爲函數加上統計時間的功能
三:編寫裝飾器,爲函數加上認證的功能
四:編寫裝飾器,爲多個函數加上認證的功能(用戶的帳號密碼來源於文件),要求登陸成功一次,後續的函數都無需再輸入用戶名和密碼
注意:從文件中讀出字符串形式的字典,能夠用eval('{"name":"egon","password":"123"}')轉成字典格式
五:編寫裝飾器,爲多個函數加上認證功能,要求登陸成功一次,在超時時間內無需重複登陸,超過了超時時間,則必須從新登陸
六:編寫下載網頁內容的函數,要求功能是:用戶傳入一個url,函數返回下載頁面的結果
七:爲題目五編寫裝飾器,實現緩存網頁內容的功能:
具體:實現下載的頁面存放於文件中,若是文件內有值(文件大小不爲0),就優先從文件中讀取網頁內容,不然,就去下載,而後存到文件中
擴展功能:用戶能夠選擇緩存介質/緩存引擎,針對不一樣的url,緩存到不一樣的文件中
八:還記得咱們用函數對象的概念,製做一個函數字典的操做嗎,來來來,咱們有更高大上的作法,在文件開頭聲明一個空字典,而後在每一個函數前加上裝飾器,完成自動添加到字典的操做
九 編寫日誌裝飾器,實現功能如:一旦函數f1執行,則將消息2017-07-21 11:12:11 f1 run寫入到日誌文件中,日誌文件路徑能夠指定
注意:時間格式的獲取
import time
time.strftime('%Y-%m-%d %X')
#題目一: import time,random ran = random.random() def foo(): time.sleep(ran) print("Done") foo() #題目二: import time,random ran = random.random() def timer(func): def inner(): start_time = time.time() func() stop_time = time.time() print("TIME>> %s" %(stop_time-start_time)) return inner @timer def foo(): time.sleep(ran) print("Done") foo() #題目三: import time,random ran = random.random() def auth(bar): def inner(): info = { "lizhong":123, "hehe":234, } name = input("user>>").strip() if name in info: pwd = int(input("pwd>>").strip()) if pwd == info[name]: print("Login success") bar() else: print("Login faild") else: print("No such user") return inner def timer(func): def inner(): start_time = time.time() func() stop_time = time.time() print("TIME>> %s" %(stop_time-start_time)) return inner @auth @timer def foo(): time.sleep(ran) print("Done") while True: foo() #題目四: db='db.txt' login_status={'user':None,'status':False} def auth(auth_type='file'): def auth2(func): def wrapper(*args,**kwargs): if login_status['user'] and login_status['status']: return func(*args,**kwargs) if auth_type == 'file': with open(db,encoding='utf-8') as f: dic=eval(f.read()) name=input('username: ').strip() password=input('password: ').strip() if name in dic and password == dic[name]: login_status['user']=name login_status['status']=True res=func(*args,**kwargs) return res else: print('username or password error') elif auth_type == 'sql': pass else: pass return wrapper return auth2 @auth() def index(): print('index') @auth(auth_type='file') def home(name): print('welcome %s to home' %name) # index() # home('egon') #題目五 import time,random user={'user':None,'login_time':None,'timeout':0.000003,} def timmer(func): def wrapper(*args,**kwargs): s1=time.time() res=func(*args,**kwargs) s2=time.time() print('%s' %(s2-s1)) return res return wrapper def auth(func): def wrapper(*args,**kwargs): if user['user']: timeout=time.time()-user['login_time'] if timeout < user['timeout']: return func(*args,**kwargs) name=input('name>>: ').strip() password=input('password>>: ').strip() if name == 'egon' and password == '123': user['user']=name user['login_time']=time.time() res=func(*args,**kwargs) return res return wrapper @auth def index(): time.sleep(random.randrange(3)) print('welcome to index') @auth def home(name): time.sleep(random.randrange(3)) print('welcome %s to home ' %name) index() home('egon') #題目六: import requests import os def wget(url): res = requests.get(url) return res print(wget("http://baidu.com/")) #題目七:簡單版本 import requests import os cache_file='cache.txt' def make_cache(func): def wrapper(*args,**kwargs): if not os.path.exists(cache_file): with open(cache_file,'w'):pass if os.path.getsize(cache_file): with open(cache_file,'r',encoding='utf-8') as f: res=f.read() else: res=func(*args,**kwargs) with open(cache_file,'w',encoding='utf-8') as f: f.write(res) return res return wrapper @make_cache def get(url): return requests.get(url).text # res=get('https://www.python.org') # print(res) #題目七:擴展版本 import requests,os,hashlib engine_settings={ 'file':{'dirname':'./db'}, 'mysql':{ 'host':'127.0.0.1', 'port':3306, 'user':'root', 'password':'123'}, 'redis':{ 'host':'127.0.0.1', 'port':6379, 'user':'root', 'password':'123'}, } def make_cache(engine='file'): if engine not in engine_settings: raise TypeError('egine not valid') def deco(func): def wrapper(url): if engine == 'file': m=hashlib.md5(url.encode('utf-8')) cache_filename=m.hexdigest() cache_filepath=r'%s/%s' %(engine_settings['file']['dirname'],cache_filename) if os.path.exists(cache_filepath) and os.path.getsize(cache_filepath): return open(cache_filepath,encoding='utf-8').read() res=func(url) with open(cache_filepath,'w',encoding='utf-8') as f: f.write(res) return res elif engine == 'mysql': pass elif engine == 'redis': pass else: pass return wrapper return deco @make_cache(engine='file') def get(url): return requests.get(url).text # print(get('https://www.python.org')) print(get('https://www.baidu.com')) #題目八 route_dic={} def make_route(name): def deco(func): route_dic[name]=func return deco @make_route('select') def func1(): print('select') @make_route('insert') def func2(): print('insert') @make_route('update') def func3(): print('update') @make_route('delete') def func4(): print('delete') print(route_dic) #題目九 import time import os def logger(logfile): def deco(func): if not os.path.exists(logfile): with open(logfile,'w'):pass def wrapper(*args,**kwargs): res=func(*args,**kwargs) with open(logfile,'a',encoding='utf-8') as f: f.write('%s %s run\n' %(time.strftime('%Y-%m-%d %X'),func.__name__)) return res return wrapper return deco @logger(logfile='aaaaaaaaaaaaaaaaaaaaa.log') def index(): print('index') index()
一 迭代的概念
#迭代是一個重複的過程,每次重複即一次迭代,而且每次迭代的結果都是下一次迭代的初始值 while True: #只是單純地重複,於是不是迭代 print('===>') l=[1,2,3] count=0 while count < len(l): #迭代 print(l[count]) count+=1
二 爲什麼要有迭代器?什麼是可迭代對象?什麼是迭代器對象?
#一、爲什麼要有迭代器? 對於序列類型:字符串、列表、元組,咱們可使用索引的方式迭代取出其包含的元素。但對於字典、集合、文件等類型是沒有索引的,若還想取出其內部包含的元素,則必須找出一種不依賴於索引的迭代方式,這就是迭代器 #二、什麼是可迭代對象? 可迭代對象指的是內置有__iter__方法的對象,即obj.__iter__,以下 'hello'.__iter__ (1,2,3).__iter__ [1,2,3].__iter__ {'a':1}.__iter__ {'a','b'}.__iter__ open('a.txt').__iter__ #三、什麼是迭代器對象? 可迭代對象執行obj.__iter__()獲得的結果就是迭代器對象 而迭代器對象指的是即內置有__iter__又內置有__next__方法的對象 文件類型是迭代器對象 open('a.txt').__iter__() open('a.txt').__next__() #四、注意: 迭代器對象必定是可迭代對象,而可迭代對象不必定是迭代器對象
三 迭代器對象的使用
dic={'a':1,'b':2,'c':3} iter_dic=dic.__iter__() #獲得迭代器對象,迭代器對象即有__iter__又有__next__,可是:迭代器.__iter__()獲得的仍然是迭代器自己 iter_dic.__iter__() is iter_dic #True print(iter_dic.__next__()) #等同於next(iter_dic) print(iter_dic.__next__()) #等同於next(iter_dic) print(iter_dic.__next__()) #等同於next(iter_dic) # print(iter_dic.__next__()) #拋出異常StopIteration,或者說結束標誌 #有了迭代器,咱們就能夠不依賴索引迭代取值了 iter_dic=dic.__iter__() while 1: try: k=next(iter_dic) print(dic[k]) except StopIteration: break #這麼寫太醜陋了,須要咱們本身捕捉異常,控制next,python這麼牛逼,能不能幫我解決呢?能,請看for循環
四 for循環
#基於for循環,咱們能夠徹底再也不依賴索引去取值了 dic={'a':1,'b':2,'c':3} for k in dic: print(dic[k]) #for循環的工做原理 #1:執行in後對象的dic.__iter__()方法,獲得一個迭代器對象iter_dic #2: 執行next(iter_dic),將獲得的值賦值給k,而後執行循環體代碼 #3: 重複過程2,直到捕捉到異常StopIteration,結束循環
五 迭代器的優缺點
#優勢: - 提供一種統一的、不依賴於索引的迭代方式 - 惰性計算,節省內存 #缺點: - 沒法獲取長度(只有在next完畢才知道到底有幾個值) - 一次性的,只能日後走,不能往前退
一 什麼是生成器
#只要函數內部包含有yield關鍵字,那麼函數名()的到的結果就是生成器,而且不會執行函數內部代碼 def func(): print('====>first') yield 1 print('====>second') yield 2 print('====>third') yield 3 print('====>end') g=func() print(g) #<generator object func at 0x0000000002184360>
二 生成器就是迭代器
g.__iter__ g.__next__ #二、因此生成器就是迭代器,所以能夠這麼取值 res=next(g) print(res)
三 練習
一、自定義函數模擬range(1,7,2)
二、模擬管道,實現功能:tail -f access.log | grep '404'
#題目一: def my_range(start,stop,step=1): while start < stop: yield start start+=step #執行函數獲得生成器,本質就是迭代器 obj=my_range(1,7,2) #1 3 5 print(next(obj)) print(next(obj)) print(next(obj)) print(next(obj)) #StopIteration #應用於for循環 for i in my_range(1,7,2): print(i) #題目二 import time def tail(filepath): with open(filepath,'rb') as f: f.seek(0,2) while True: line=f.readline() if line: yield line else: time.sleep(0.2) def grep(pattern,lines): for line in lines: line=line.decode('utf-8') if pattern in line: yield line for line in grep('404',tail('access.log')): print(line,end='') #測試 with open('access.log','a',encoding='utf-8') as f: f.write('出錯啦404\n')
四 協程函數
#yield關鍵字的另一種使用形式:表達式形式的yield def eater(name): print('%s 準備開始吃飯啦' %name) food_list=[] while True: food=yield food_list print('%s 吃了 %s' % (name,food)) food_list.append(food) g=eater('egon') g.send(None) #對於表達式形式的yield,在使用時,第一次必須傳None,g.send(None)等同於next(g) g.send('蒸羊羔') g.send('蒸鹿茸') g.send('蒸熊掌') g.send('燒素鴨') g.close() g.send('燒素鵝') g.send('燒鹿尾')
五 練習
一、編寫裝飾器,實現初始化協程函數的功能
二、實現功能:grep -rl 'python' /etc
#題目一: def init(func): def wrapper(*args,**kwargs): g=func(*args,**kwargs) next(g) return g return wrapper @init def eater(name): print('%s 準備開始吃飯啦' %name) food_list=[] while True: food=yield food_list print('%s 吃了 %s' % (name,food)) food_list.append(food) g=eater('egon') g.send('蒸羊羔') #題目二: #注意:target.send(...)在拿到target的返回值後纔算執行結束 import os def init(func): def wrapper(*args,**kwargs): g=func(*args,**kwargs) next(g) return g return wrapper @init def search(target): while True: filepath=yield g=os.walk(filepath) for dirname,_,files in g: for file in files: abs_path=r'%s\%s' %(dirname,file) target.send(abs_path) @init def opener(target): while True: abs_path=yield with open(abs_path,'rb') as f: target.send((f,abs_path)) @init def cat(target): while True: f,abs_path=yield for line in f: res=target.send((line,abs_path)) if res: break @init def grep(pattern,target): tag=False while True: line,abs_path=yield tag tag=False if pattern.encode('utf-8') in line: target.send(abs_path) tag=True @init def printer(): while True: abs_path=yield print(abs_path) g=search(opener(cat(grep('你好',printer())))) # g.send(r'E:\CMS\aaa\db') g=search(opener(cat(grep('python',printer())))) g.send(r'E:\CMS\aaa\db')
六 yield總結
#一、把函數作成迭代器 #二、對比return,能夠返回屢次值,能夠掛起/保存函數的運行狀態
#一、首先強調:面向過程編程絕對不是用函數編程這麼簡單,面向過程是一種編程思路、思想,而編程思路是不依賴於具體的語言或語法的。言外之意是即便咱們不依賴於函數,也能夠基於面向過程的思想編寫程序 #二、定義 面向過程的核心是過程二字,過程指的是解決問題的步驟,即先幹什麼再幹什麼 基於面向過程設計程序就比如在設計一條流水線,是一種機械式的思惟方式 #三、優勢:複雜的問題流程化,進而簡單化 #四、缺點:可擴展性差,修改流水線的任意一個階段,都會牽一髮而動全身 #五、應用:擴展性要求不高的場景,典型案例如linux內核,git,httpd #六、舉例 流水線1: 用戶輸入用戶名、密碼--->用戶驗證--->歡迎界面 流水線2: 用戶輸入sql--->sql解析--->執行功能
name=input('姓名>>: ') res='SB' if name == 'alex' else 'NB' print(res)
#一、示例 egg_list=[] for i in range(10): egg_list.append('雞蛋%s' %i) egg_list=['雞蛋%s' %i for i in range(10)] #二、語法 [expression for item1 in iterable1 if condition1 for item2 in iterable2 if condition2 ... for itemN in iterableN if conditionN ] 相似於 res=[] for item1 in iterable1: if condition1: for item2 in iterable2: if condition2 ... for itemN in iterableN: if conditionN: res.append(expression) #三、優勢:方便,改變了編程習慣,可稱之爲聲明式編程
#一、把列表推導式的[]換成()就是生成器表達式 #二、示例:生一筐雞蛋變成給你一隻老母雞,用的時候就下蛋,這也是生成器的特性 >>> chicken=('雞蛋%s' %i for i in range(5)) >>> chicken <generator object <genexpr> at 0x10143f200> >>> next(chicken) '雞蛋0' >>> list(chicken) #因chicken可迭代,於是能夠轉成列表 ['雞蛋1', '雞蛋2', '雞蛋3', '雞蛋4',] #三、優勢:省內存,一次只產生一個值在內存中
一、將names=['egon','alex_sb','wupeiqi','yuanhao']中的名字所有變大寫
二、將names=['egon','alex_sb','wupeiqi','yuanhao']中以sb結尾的名字過濾掉,而後保存剩下的名字長度
三、求文件a.txt中最長的行的長度(長度按字符個數算,須要使用max函數)
四、求文件a.txt中總共包含的字符個數?思考爲什麼在第一次以後的n次sum求和獲得的結果爲0?(須要使用sum函數)
五、思考題
with open('a.txt') as f: g=(len(line) for line in f) print(sum(g)) #爲什麼報錯?
六、文件shopping.txt內容以下
求總共花了多少錢?
打印出全部商品的信息,格式爲[{'name':'xxx','price':333,'count':3},...]
求單價大於10000的商品信息,格式同上
#題目一 names=['egon','alex_sb','wupeiqi','yuanhao'] names=[name.upper() for name in names] #題目二 names=['egon','alex_sb','wupeiqi','yuanhao'] names=[len(name) for name in names if not name.endswith('sb')] #題目三 with open('a.txt',encoding='utf-8') as f: print(max(len(line) for line in f)) #題目四 with open('a.txt', encoding='utf-8') as f: print(sum(len(line) for line in f)) print(sum(len(line) for line in f)) #求包換換行符在內的文件全部的字符數,爲什麼獲得的值爲0? print(sum(len(line) for line in f)) #求包換換行符在內的文件全部的字符數,爲什麼獲得的值爲0? #題目五(略) #題目六:每次必須從新打開文件或seek到文件開頭,由於迭代完一次就結束了 with open('a.txt',encoding='utf-8') as f: info=[line.split() for line in f] cost=sum(float(unit_price)*int(count) for _,unit_price,count in info) print(cost) with open('a.txt',encoding='utf-8') as f: info=[{ 'name': line.split()[0], 'price': float(line.split()[1]), 'count': int(line.split()[2]), } for line in f] print(info) with open('a.txt',encoding='utf-8') as f: info=[{ 'name': line.split()[0], 'price': float(line.split()[1]), 'count': int(line.split()[2]), } for line in f if float(line.split()[1]) > 10000] print(info)
以前咱們學習過用eval內置方法能夠將一個字符串轉成python對象,不過,eval方法是有侷限性的,對於普通的數據類型,json.loads和eval都能用,但遇到特殊類型的時候,eval就無論用了,因此eval的重點仍是一般用來執行一個字符串表達式,並返回表達式的值。
import json x="[null,true,false,1]" print(eval(x)) #報錯,沒法解析null類型,而json就能夠 print(json.loads(x))
什麼是序列化?
咱們把對象(變量)從內存中變成可存儲或傳輸的過程稱之爲序列化,在Python中叫pickling,在其餘語言中也被稱之爲serialization,marshalling,flattening等等,都是一個意思。
爲何要序列化?
1:持久保存狀態
需知一個軟件/程序的執行就在處理一系列狀態的變化,在編程語言中,'狀態'會以各類各樣有結構的數據類型(也可簡單的理解爲變量)的形式被保存在內存中。
內存是沒法永久保存數據的,當程序運行了一段時間,咱們斷電或者重啓程序,內存中關於這個程序的以前一段時間的數據(有結構)都被清空了。
在斷電或重啓程序以前將程序當前內存中全部的數據都保存下來(保存到文件中),以便於下次程序執行可以從文件中載入以前的數據,而後繼續執行,這就是序列化。
具體的來講,你玩使命召喚闖到了第13關,你保存遊戲狀態,關機走人,下次再玩,還能從上次的位置開始繼續闖關。或如,虛擬機狀態的掛起等。
2:跨平臺數據交互
序列化以後,不只能夠把序列化後的內容寫入磁盤,還能夠經過網絡傳輸到別的機器上,若是收發的雙方約定好實用一種序列化的格式,那麼便打破了平臺/語言差別化帶來的限制,實現了跨平臺數據交互。
反過來,把變量內容從序列化的對象從新讀到內存裏稱之爲反序列化,即unpickling。
如何序列化之json和pickle:
json
若是咱們要在不一樣的編程語言之間傳遞對象,就必須把對象序列化爲標準格式,好比XML,但更好的方法是序列化爲JSON,由於JSON表示出來就是一個字符串,能夠被全部語言讀取,也能夠方便地存儲到磁盤或者經過網絡傳輸。JSON不只是標準格式,而且比XML更快,並且能夠直接在Web頁面中讀取,很是方便。
JSON表示的對象就是標準的JavaScript語言的對象,JSON和Python內置的數據類型對應以下:
import json dic={'name':'alvin','age':23,'sex':'male'} print(type(dic))#<class 'dict'> j=json.dumps(dic) print(type(j))#<class 'str'>
json.dump(obj,文件對象(w方式))
json.load(文件對象(r模式)
f=open('序列化對象','w') f.write(j) #-------------------等價於json.dump(dic,f) f.close() #-----------------------------反序列化<br> import json f=open('序列化對象') data=json.loads(f.read())# 等價於data=json.load(f)
pickle
import pickle dic={'name':'alvin','age':23,'sex':'male'} print(type(dic))#<class 'dict'> j=pickle.dumps(dic) print(type(j))#<class 'bytes'> f=open('序列化對象_pickle','wb')#注意是w是寫入str,wb是寫入bytes,j是'bytes' f.write(j) #-------------------等價於pickle.dump(dic,f) f.close() #-------------------------反序列化 import pickle f=open('序列化對象_pickle','rb') data=pickle.loads(f.read())# 等價於data=pickle.load(f) print(data['age'])
Pickle的問題和全部其餘編程語言特有的序列化問題同樣,就是它只能用於Python,而且可能不一樣版本的Python彼此都不兼容,所以,只能用Pickle保存那些不重要的數據,不能成功地反序列化也不要緊。