裝飾器:
定義:本質是函式,功能是裝飾其他函式,就是為其他函數新增附加功能。
原則:1、不能修改被裝飾的函式的原始碼。
2、不能修改被裝飾的函式的呼叫方式,呼叫還是用原函式名加(),但附加功能在裡面。
高階函式+巢狀函式==》裝飾器
函式即變數。巢狀函式:在一個函式的函式體內,宣告一個函式,而不是呼叫一個函式。
#example: import time def pisiwace(func): def deco(*args,**kwargs): 'coefficient correction' # args[0]+=2 # args[1]=args[1]*2 # args[2]+=1 time_start=time.time() func(*args,**kwargs) time_end=time.time() print('Interval time: %s '%(time_end-time_start)) return deco @pisiwace#test1=pisiwace(test1) def test1(x,y=2): "calculation" y=x**2+x*y time.sleep(2) print(x,y) return x,y @pisiwace#test2=pisiwace(test2) def test2(x,y,z): "calculation" y=x**2+x*y+z time.sleep(3) print(x,y,z) return x,y test1(2) test2(1,2,3)
當有多個裝飾器本身存在引數時,可用多個函式巢狀。@login('remote')#home=login('remote')(home)
#example usename,password='wulihui',123456 def login(choise): if choise=='local': def option(func): def wrapper(x): _usename=input('usename:') _password=int(input('password:')) print(x) if usename==_usename and password==_password: source=func() return source else: print('invalid username or password') return wrapper return option elif choise=='remote': print('remote login connectting') def remote_login(x): 'remote login' return x return remote_login def _index(): 'index page' print('welcome to index page') return 'from index' @login('remote')#home=login('remote')(home) def home(): 'home page' print('welcome to home page') return 'from home' @login('local')#bbs=login(‘local’)(bbs) def bbs(): 'bbs page' print('welcome to bbs page') return 'from bbs' print(_index()) print(home()) print(bbs(3))
生成器:生成器一邊迴圈,一邊計算,生成器只有在呼叫的時候才能生成資料,比較節省記憶體。
#列表生成式
a=[i*3 for i in range(1,11,2)] print(a)
#生成器
gen1=(i*3 for i in range(1,11,2) )#定義生成器gen1 print(gen1.__next__())#取生成器中當前位置的下一個生成值,無法回到前一個值,只能逐個往後取 print(gen1.__next__()) print(gen1.__next__())
#迴圈呼叫
for i in gen1: print(i) # def fib(nmb):#這是函式 # n,a,b=0,0,1 # while n<nmb: # print(b) # a,b=b,a+b # n+=1 # return 'done' # fib(10)
元組知識補充
a,b=1,2#a=1,b=2,類似(a,b)=(1,2) a,b=b,a+b#此時先計算元組tuple=(a,a+b)=(2,1+2)=(2,3),再賦值,a=tuple[0],b=tuple[1] print(a,b)
#函式式生成器
def fib(nmb): n,a,b=0,0,1 while n<nmb: yield b#此時feb(nmb)為一個生成器,返回當前值,保留函式的中斷狀態 #print(b) a,b=b,a+b#含義參照tuple_knowledge.py n+=1 return 'done' #print(feb(10)) gen2=fib(10) print(gen2.__next__()) print(''.center(50,'-'))#中間可以插入其他操作 print(gen2.__next__()) print(gen2.__next__()) print(gen2.__next__()) print(gen2.__next__()) print(gen2.__next__()) print(gen2.__next__()) print(gen2.__next__()) print(gen2.__next__()) print(gen2.__next__()) print(gen2.__next__()) print(gen2.__next__())#next次數超過10會報錯,報的為return的值 # #異常 # g=fib(10) # while True: # try: # x=next(g) # print('g:',x) # except StopIteration as e: # print('generator return value:',e.value) # break
#生成器協程處理
import time def consumer(name): 'consumer generator' print('consumer %s is coming'%name) while True: baozi=yield print('steamed stuffed bun %s is coming .And it is eat by %s.'%(baozi,name)) return 'coming' def productor(): 'productor generator' c1=consumer('A') c1.__next__() c2=consumer('B') c2.__next__() print('we have prepared steamed stuffed bun') baozi_list=['肉包','菜包','花捲','糖包','灌湯包'] for i in baozi_list: print('包子做好了') c1.send(i) c2.send(i) time.sleep(1) return 'done' productor() #判斷是否可迴圈 from collections import Iterable gen1=consumer('op') print(isinstance(gen1,Iterable))
迭代器:
可迭代物件:可直接作用於for迴圈的物件,稱為可迭代物件
判斷是否為可迭代物件方法:
from collections import Iterable print(isinstance([1,2],Iterable))
可以被next()函式呼叫,並不斷返回下一個值的物件,稱為迭代器物件:Iterator
#判斷是否為迭代器物件
from collections import Iterator print(isinstance((i+2 for i in range(10)),Iterator)) print(isinstance([i+2 for i in range(10)],Iterator))
#iter(o),將list、dict、set、str變成可迭代物件
print(isinstance(iter([1,2]),Iterator))
迭代器原理:
for i in [1,2,3,4]: pass #原理如下 it=iter([1,2,3,4]) while True: try: #獲得下一個值 x=next(it) except StopIteration: #遇到StopIteration就退出迴圈 break
計算時間間隔的函式
import time def time_count(): time_start=time.time() time.sleep(1.5) time_end=time.time() print('time count is %s'%(time_end-time_start)) time_count()
匿名函式
def sayhi(n): print(n) sayhi(3) #改成匿名函式,即沒有def sayhai=lambda n:print(n) sayhi(2) anonymous=lambda x:x*2 print(anonymous(4))
內建函式:
內建函式也叫內建方法。
#all(Iterable):判斷裡的元素是否都為真,是的話為True,否則為False.當Iterable裡存在0和False時,all(Iterable)為False print(all([2,-3,'OFF'])) print(all({0,False,3})) #any:判斷裡的元素是否存在真值,存在的話為True,否則為False.當Iterable裡只有0和False時或什麼都沒有時,any(Iterable)為False print(any([])) print(any({0,False})) #ascill()把一個記憶體物件變成可列印的字串形式 c={'China':'Chinese','England':'English','Japen':'Japenese'} b=ascii(c) print(type(c),c) print(type(b),{b}) #bin():將十進位制整數轉化為二進位制表示 print(bin(63)) #bool()判斷真假,0和空為假,其他為真,在可迭代物件裡,存在元素即為真(包括0) print(bool(1)) print(bool(0)) print(bool('0')) #bytes(object,encoding=),將object轉化為位元組格式,位元組格式不能修改 print(bytes('wulihui',encoding='utf-8')) #bytearray(object,encoding=):轉化為ascii碼陣列,可以進行修改 d=bytearray('wu',encoding='utf-8') print(d,d[0]) d[0]=121 print(d,d[0]) #callable(object):判斷object是否可以呼叫,函式和類 def test(): pass print(callable(test)) print(callable([1,2])) #chr(code),將整數返回ascii碼的對應形式 print(chr(97)) #反過來講ascii碼字元轉化為數字ord() print(ord('a')) #compile(object,'error.log','eval/exec'):將字串轉化為可執行物件,error.log一個檔名,執行時有錯誤會寫進去,’eval/exec‘執行器 code='for i in range(10):print(i)' com=compile(code,'','exec') exec(com)#直接exec(code)也行,效果一樣 #exec(code) #complex()複數 print(complex(1-2j)) #dict()生成一個字典 print(dict(name='wu')) #dir(object)檢視object的引用方法 print(dir([])) #divmod(a,b):a/b返回商和餘數,a,b必須為兩個數 print(divmod(5,2)) #enumerate()#取出可迭代物件的序號和元素 list_1=['wu','dai','li'] for index,value in enumerate(list_1): print(index,value) #eval()把字串變成字典、列表、集合等物件,處理加減乘除運算,不能處理存在語句的物件 dict1="{'China':'Chinese','England':'English'}" list1='[1,2,3]' y='2*3+4/2' print(type(dict1),type(list1)) dict1=eval(dict1) list1=eval(list1) print(dict1['China'],list1[0]) print(eval(y)) #exec():將字串轉化為可執行物件,可以處理語句或函式的物件 code=''' def sayhi(): print('hi') sayhi()''' exec(code) #filter(function,Iterable),對可迭代物件生成的資料進行過濾,function為過濾函式 filter1=filter(lambda n: n>3,range(10))#把為真的值選出來 for i in filter1: print(i) #map(function,Iterable)對可迭代物件生成的資料進行處理,function為處理函式 map1=map(lambda n:n>3,range(10))#判斷是否為真 for i in map1: print(i) map2=map(lambda i:i*2,range(10))#相當於map2=[i*2 for i in range(10)] #reduce(): import functools reduce1=functools.reduce(lambda x,y:x+y*2,range(4))#range()裡的值賦給y print(reduce1) #flout()轉成浮點型別 #format():格式轉換 print(format(2918))#轉成str print(format(0x500, 'X'))#轉成16進位制 print(format(3.14, '010'))#顯示10位數,在整數左邊補0,等號可以省略010,超過10位則不變,小數點算一位 print(format(3.14159, '05.3'))#四捨五入保留3位有效數字,並顯示5位,小數點算一位 print(format(3.14159, 'E'))#改成科學計數法 print(format('test', '<20'))#站位20個,左對齊 print(format('test', '>20'))#站位20個,右對齊 print(format('test', '^20'))#站位20個,居中對齊 print(format(-3.14159, '+'))#顯示正負號,與‘-’同 #frozenset()不可變的集合,無法添和刪 #globals()#生成一個字典,返回當前程式所有全域性變數的key:value格式 print(globals()) print(globals().get('list_1')) #hash(object):將object轉化為一個數字,形成對映,方便查詢 print(hash('wulihui')) #help檢視幫助 help(format) #hex():轉成16進位制 print(hex(56)) #id():返回記憶體地址 numb23=23 print(id(numb23)) #locals():#生成一個字典,返回當前位置所有區域性變數的key:value格式,一般放在函式等內部 print(locals()) #max():返回最大值 print(max([123,455,66])) print(max({1,3,5,99999,45,7})) print(max(1,3,5,9,45,7)) print(max({1:2,3:13,5:999999,9:44,45:20,7:33}))#選出最大的key #min():返回最小值 #oct():轉8進位制 print(oct(10)) #pow(a,b):計算a**b print(pow(3,4)) #repr(o):用字串表示物件,相當於ascii(),把一個記憶體物件變成可列印的字串形式 #reversed(o):翻轉,把序列反過來,第一個變成最後一個 #round(a,num):圓整,四捨五入保留幾位小數,num為保留小數位數 print(round(3.141592653,3)) #slice(start,stop):切片 list_2=[0,1,2,3,5,6,7,8,9,10] print(list_2[slice(2,8,2)])#取list_2[2:8:2] print(list_2[2:8:2])#結果同上 list_3=range(10) list_4=list_3[slice(2,8)] print(list_4) for i in list_4: print(i) #sorted(iterable, key=None, reverse=False): 以升序返回包含iterable中所有項的新列表。 dict2={1:2,-3:9,5:10,7:-9,8:8} print(sorted(dict2.items()))#對字典轉化成的元組進行排序,預設以元組中第一個元素排序,升序 print(sorted(dict2.items(),key=lambda x:x[1],reverse=True))#以value進行排序,降序 #sum(iterable, start=0, /):返回'start'值的總和(預設值:0)加上可迭代的數字 print(sum(range(5),10))#0+1+2+3+4+10 #zip(o):把兩個可迭代物件拼起來,元素個數不匹配,按照少的進行匹配,當最短的可迭代用盡時停止。 list_a=[1,2,3,4] list_b=['a','b','c','d'] list_c=zip(list_a,list_b) for i in list_c: print(i) #__import__(name, globals=None, locals=None, fromlist=(), level=0) :匯入模組 __import__('anonymous function')#相當於import anonymous function
json&pickle序列化:
檔案只能以字串或者二進位制進行儲存。序列化:把記憶體物件轉化為字串。
#將記憶體物件存入檔案 set_1={'China':'Chinese','UK':'English'} with open('test.txt','w',encoding='utf-8') as f: f.write(str(set_1)) #標準的序列化方法: import json with open('text2.txt','w',encoding='utf-8') as f : f.write(json.dumps(set_1)) #json.dump(set_1,f)功能同上 #json.dumps(o):將``obj``序列化為JSON格式的``str``。 #json 只能處理簡單的資料,例如字典、列表等,json在所有語言中都是互通的,主要用於各個語言之間的轉換 # 以下情況處理不了 # def sayhi(name): # print('hi,%s'%name) # set_2={'China':'Chinese', # 'func':sayhi} # json.dumps(set_2) ####pickle 序列化,pickle可以序列化python裡的所有型別,用法和json完全相同,轉化成了bytes型別,pickle只能在python裡用 import pickle def sayhi(name): print('hi,%s'%name) set_2={'China':'Chinese', 'func':sayhi} with open('text3.txt','wb') as f2: #f2.write(pickle.dumps(set_2))#功能同下 pickle.dump(set_2,f2) #dump序列化json.dump(o,fp):將``obj``序列化為JSON格式化的流為``fp``(a``.write()`` - 支援類檔案物件)。 #不要在一個檔案裡dump多次,需要存多個dump時,分開存在多個檔案裡
json&pickle序列化:
#反序列化 with open('test.txt','r',encoding='utf-8') as f: data=f.read() print(data) data1=eval(data) print(data1['China']) #標準json反序列化: import json with open('text2.txt','r',encoding='utf-8') as f1 : data3=json.loads(f1.read())#等同於data3=json.load(f1) print(data3['UK']) #pickle 反序列化,pickle只能在python語言裡可用 import pickle def sayhi(name): print('hi,%s'%name) with open('text3.txt','rb') as f2: data4=pickle.loads(f2.read())#等同於data4=pickle.load(f2) data4['func']('wulihui')
列印檔案的路徑和匯入環境變數:
print(__file__)#列印當前程式檔案的相對路徑(執行程式的路徑) import os print(os.path.abspath(__file__))#列印當前程式檔案的絕對路徑(檔案所在路徑) print(os.path.dirname(os.path.abspath(__file__)))#列印當前程式檔案的目錄路徑(上一級目錄) general_content=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) print(general_content) #宣告環境變數 import sys sys.path.append(general_content) import day1 from day1 import homework2#匯入general_content/day1/homework2檔案
Project的標準目錄結構:
Foo/#程式名
|--Readme#專案說明檔案
|--bin |--foo#執行程式入口,程式啟動入口,呼叫main.py
|--conf#配置檔案
|foo/#主程式目錄
| |--tests/#測試用例,存放單元測試程式碼
| | |--__init__.py
| | |--test_main.py
| |
| |--__init__.py
| |--main.py#主程式原始碼存放,程式主入口
|
|--docs/文件存放
| |--conf.py
| |--abc.rst
|
|--setup.py#安裝部署指令碼
|--requirements.txt#依賴關係,存放軟體依賴的外部包列表
Readme 應當包含以下部分:
1、軟體定位,軟體的基本功能
2、執行程式碼的方法、安裝環境、啟動命令等
3、簡要的使用說明
4、程式碼目錄結構說明,更詳細點可以說明軟體的基本原理
5、常見問題說明