寫代碼的方式:面向過程 --> 函數式編程(多) --> 面向對象編程。python
def func(a1,a2): pass result = func(1,2)
補充:對於函數的默認值慎用可變類型。面試
# 若是要想給value設置默認是空列表 # 不推薦(坑) def func(data,value=[]): pass # 推薦 def func(data,value=None): if not value: value = []
def func(data,value=[]): value.append(data) return value v1 = func(1) # [1,] v2 = func(1,[11,22,33]) # [11,22,33,1]
面試題:django
def func(a,b=[]) 有什麼陷阱?#若是使用b=[]默認參數,傳遞參數默認都是都是用同一個地址。編程
看代碼寫結果flask
def func(a,b=[]): b.append(a) return b l1 = func(1) l2 = func(2,[11,22]) l3 = func(3) # [1,3] [11,22,2] [1,3] print(l1,l2,l3) #函數默認參數,已經在函數建立的時候在內部已經佔用內存。若是調用函數時候,沒有指定默認參數值的時候,函數會主動調用默認參數的內存,不斷的調用函數,不斷的向默認參數內存中填充數據。因此會出現打印l1和l3結果相同。
看代碼寫結果緩存
def func(a,b=[]): b.append(a) print(b) func(1) func(2,[11,22,33]) func(3) #這題區別上題,直接執行函數。執行func(1)時候,func(3)尚未向默認內存空間中存數據。 # [1] [11,22,33,2] [1,3]
1.3 返回值閉包
分析函數執行的內存app
def func(name): def inner(): print(name)#使用分配的內存 return 123 return inner v1 = func('alex') v2 = func('eric') v1() v2()
閉包#經過函數嵌套,將值保存起來,方便後期調用。框架
# 不是閉包 def func1(name):#封裝值,可是沒用 def inner(): return 123 return inner # 是閉包:封裝值 + 內層函數須要使用。 def func2(name):#封住了值,在嵌套函數中被使用了。 def inner(): print(name) return 123 return inner
函數本身調用本身。(效率低),儘可能使用while循環。dom
限制遞歸次數:作多遞歸1000次。
def func(): print(1) func() func()
def func(i): print(i) func(i+1) func(1)
#取出斐波那契數 def func(a,b): # 1 # 1 # 2 # 3 # 5 print(b) func(b,a+b) func(0,1)
def func(a): if a == 5: return 100000#100000+4*10 result = func(a+1) + 10 return result v = func(1)
# 遞歸的返回值 def func(a): if a == 5: return 100000 result = func(a+1) + 10 v = func(1) name = 'alex' def func(): def inner(): print(name) return inner v =func()
def x(func): def inner(): return func() return inner @x def index(): pass
def x(func): def inner(a1): return func(a1) return inner @x def index(a1): pass
def x(func): def inner(a1,a2): return func(a1,a2) return inner @x def index(a1,a2): pass # index = inner index(1,2) # ################################### 參數統一的目的是爲了給原來的index函數傳參 def x(func): def inner(a1,a2): return func() return inner @x def index(): pass # func = 原來的index函數u # index = inner index(1,2)
若是給好幾個函數寫一個統一的裝飾器,怎麼辦?
def x1(func): def inner(*args,**kwargs): return func(*args,**kwargs) return inner @x1 def f1(): pass @x1 def f2(a1): pass @x1 def f3(a1,a2): pass
def x1(func): def inner(*args,**kwargs): data = func(*args,**kwargs) return data return inner @x1 def f1(): print(123) v1 = f1() print(v1)
def x1(func): def inner(*args,**kwargs): data = func(*args,**kwargs) return data return inner @x1 def f1(): print(123) return 666 v1 = f1() print(v1)
def x1(func): def inner(*args,**kwargs): data = func(*args,**kwargs) return inner @x1 def f1(): print(123) return 666 v1 = f1() print(v1)
裝飾器建議寫法:
def x1(func): def inner(*args,**kwargs): data = func(*args,**kwargs) return data return inner
def x1(func): def inner(*args,**kwargs): print('調用原函數以前') data = func(*args,**kwargs) # 執行原函數並獲取返回值 print('調用員函數以後') return data return inner @x1 def index(): print(123) index()
# 第一步:執行 ret = xxx(index) # 第二步:將返回值賦值給 index = ret @xxx def index(): pass # 第一步:執行 v1 = uuu(9) # 第二步:ret = v1(index) # 第三步:index = ret @uuu(9)#先執行帶參數9的外層函數。 def index(): pass
# ################## 普通裝飾器 ##################### def wrapper(func): def inner(*args,**kwargs): print('調用原函數以前') data = func(*args,**kwargs) # 執行原函數並獲取返回值 print('調用員函數以後') return data return inner @wrapper def index(): pass # ################## 帶參數裝飾器 ##################### def x(counter): def wrapper(func): def inner(*args,**kwargs): data = func(*args,**kwargs) # 執行原函數並獲取返回值 return data return inner return wrapper @x(9)#至關於在外層套了一個函數,函數的內部參數counter便於內部函數調用。 #如,能夠帶參數n,使得下面被裝飾的函數執行n次。 def index(): pass
練習題
# 寫一個帶參數的裝飾器,實現:參數是多少,被裝飾的函數就要執行多少次,把每次結果添加到列表中,最終返回列表。 def xxx(counter): print('x函數') def wrapper(func): print('wrapper函數') def inner(*args,**kwargs): v = [] for i in range(counter): data = func(*args,**kwargs) # 執行原函數並獲取返回值 v.append(data) return v return inner return wrapper @xxx(5) def index(): return 8 v = index() print(v) [8,8,8,8,8] # 寫一個帶參數的裝飾器,實現:參數是多少,被裝飾的函數就要執行多少次,並返回最後一次執行的結果【面試題】 def xxx(counter): print('x函數') def wrapper(func): print('wrapper函數') def inner(*args,**kwargs): for i in range(counter): data = func(*args,**kwargs) # 執行原函數並獲取返回值 return data return inner return wrapper @xxx(5) def index(): return 8 v = index() print(v) # 寫一個帶參數的裝飾器,實現:參數是多少,被裝飾的函數就要執行多少次,並返回執行結果中最大的值。 def xxx(counter): print('x函數') def wrapper(func): print('wrapper函數') def inner(*args,**kwargs): value = 0 for i in range(counter): data = func(*args,**kwargs) # 執行原函數並獲取返回值 if data > value: value = data #也能夠造成列表,max(list) return value return inner return wrapper @xxx(5) def index(): return 8 v = index() print(v)
def x(counter): print('x函數') def wrapper(func): print('wrapper函數') def inner(*args,**kwargs): if counter: return 123 return func(*args,**kwargs) return inner return wrapper #通一個裝飾器實現兩個不一樣的功能,在裝飾器使用if語句,分別實現不一樣的功能。 @x(True) def fun990(): pass @x(False) def func10(): pass
元數據:flask框架
多個裝飾器::Flask框架
@x1 @x2 def func(): pass
基本裝飾器(更重要)
def x1(func): def inner(*args,**kwargs): data = func(*args,**kwargs) # 執行原函數並獲取返回值 return data return inner @x1 def index(): print(123) index()
帶參數的裝飾器
def x(counter): def wrapper(func): def inner(*args,**kwargs): data = func(*args,**kwargs) # 執行原函數並獲取返回值 return data return inner return wrapper @x(9) def index(): pass
python解釋器相關的數據。
sys.getrefcount , 獲取一個值的應用計數
a = [11,22,33] b = a print(sys.getrefcount(a))
sys.getrecursionlimit , python默認支持的遞歸數量
sys.stdout.write --> print (進度)。pint打印最後自動換行。sys.stdout.write('xxx')最後不自動換行。
\n換行
\t製表符==tap鍵
\r,回到當前的起始位置。
print('xxx',end=' '),print中end=‘ ’表示不換行。
import time for i in range(1,101): msg = "%s%%\r" %i print(msg,end='') time.sleep(0.05)
import os # 1. 讀取文件大小(字節) file_size = os.stat('20190409_192149.mp4').st_size#獲取文件字節大小 # 2.一點一點的讀取文件 read_size = 0 with open('20190409_192149.mp4',mode='rb') as f1,open('a.mp4',mode='wb') as f2: while read_size < file_size: chunk = f1.read(1024) # (每次讀取1024個字節)每次最多去讀取1024字節 f2.write(chunk) read_size += len(chunk) val = int(read_size / file_size * 100) print('%s%%\r' %val ,end='')
sys.argv
#!/usr/bin/env python # -*- coding:utf-8 -*- """ 讓用戶執行腳本傳入要刪除的文件路徑,在內部幫助用將目錄刪除。 C:\Python36\python36.exe D:/code/s21day14/7.模塊傳參.py D:/test C:\Python36\python36.exe D:/code/s21day14/7.模塊傳參.py """ import sys # 獲取用戶執行腳本時,傳入的參數。 # C:\Python36\python36.exe D:/code/s21day14/7.模塊傳參.py D:/test # sys.argv = [D:/code/s21day14/7.模塊傳參.py, D:/test] path = sys.argv[1] # 刪除目錄 import shutil shutil.rmtree(path) #在py裏執行這個腳本,以後後面帶要刪除的目錄,便可實現刪除該目錄。
sys.path --- 欠
和操做系統相關的數據。
os.path.exists(path) , 若是path存在,返回True;若是path不存在,返回False
os.stat('20190409_192149.mp4').st_size , 獲取文件大小
os.path.abspath() , 獲取一個文件的絕對路徑
path = '20190409_192149.mp4' # D:\code\s21day14\20190409_192149.mp4 import os v1 = os.path.abspath(path) print(v1)
os.path.dirname ,獲取路徑的上級目錄
import os v = r"D:\code\s21day14\20190409_192149.mp4" #r,取消注意注意。其中出現轉義符,取消轉義。至關於在\,前加一個\。 #v2 = "D:\\code\\s21day14\\n1.mp4" print(v2) print(os.path.dirname(v))
os.path.join ,路徑的拼接
import os path = "D:\code\s21day14" # user/index/inx/fasd/,os能夠根據不一樣的系統目錄格式進行拼接。 v = 'n.txt' result = os.path.join(path,v) print(result) result = os.path.join(path,'n1','n2','n3') print(result)
os.listdir , 查看一個目錄下全部的文件【第一層】
import os result = os.listdir(r'D:\code\s21day14') for path in result: print(path)
os.walk , 查看一個目錄下全部的文件【全部層】
import os result = os.walk(r'D:\code\s21day14') for a,b,c in result: # a,正在查看的目錄 b,此目錄下的文件夾 c,此目錄下的文件 for item in c: path = os.path.join(a,item) print(path)
補充:
轉義
v1 = r"D:\code\s21day14\n1.mp4" (推薦) print(v1) v2 = "D:\\code\\s21day14\\n1.mp4" print(v2)
import shutil shutil.rmtree(path) #還能夠壓縮,解壓文件。