爲何要用裝飾器???html
在實際的開發環境中應遵循開發封閉原則,雖然在這個原則是用的面向對象開發,但也適用於函數式編程,簡單地說,它規定已經實現的功能代碼不是容許修改的,可是能夠被擴展:python
封閉:已實現的功能代碼塊web
開發:對擴展開發算法
裝飾器功能:shell
1)自動執行裝飾器下面的函數,並將被裝飾器函數的函數名當作參數傳遞給裝飾器函數編程
2)裝飾器函數的返回值,從新賦值給被裝飾函數json
#裝飾器格式:@+函數名bash
#裝飾器格式:@+函數名
def outer(func): def inner(arg): #原函數傳遞一個參數
print('before') # func() #func:表示原函數
# return func() 程序遇到return時則不執行下面函數
ret = func(arg) #func:表示獲取原函數返回值
print('after') return ret #打印原函數返回值
return func #當函數名在帶()時表示,此時函數名錶明整個函數,如加()-》表示執行函數 #自動執行outer函數而且將下面的函數名F1當作參數傳遞 #將ouetr函數的返回值,從新賦值給F1
def outer(func): def inner(*arg,**kwargs): print('before') # func() #func:表示原函數
# return func() 程序遇到return時則不執行下面函數
ret = func(*arg,**kwargs) #func:表示獲取原函數返回值
print('after') return ret #打印原函數返回值
return func #當函數名在帶()時表示,此時函數名錶明整個函數,如加()-》表示執行函數
@outer def f1(arg): #f1:原函數 #當f1裏面傳遞幾個參數時,那麼裝飾器中的函數體inner也須要傳遞給幾個參數
print(arg) @outer def f2(arg1,arg2): #傳遞多個參數時
print("F2")
1)、功能:利用代碼的可重複性,實現複雜的功能(即:在不修改源程序前提下,經過修改裝飾器傳遞參數達到執行函數的效果) app
USER_INFO={} #定義一個空的字典
USER_INFO['is_login'] #字典取值形式爲key, Value形式,若是此時只取key,不取value時,系統則報錯 #字典取值形式爲key, Value形式,若是此時字典中沒有value時,可定義一個None值,這樣當取不到字典中的value值,則系統返回None值
USER_INFO.get('is_login',None) #定義一個裝飾器
def check_login(func): #03此時func只的是check_admin中inner函數
def inner(*args,**kwargs): if USER_INFO.get('is_login',None): #默認狀況下,用戶不存在,則返回值爲None
ret1 = func(*args,**kwargs) # 04此時func表明指的check_admin-》inner函數下
return ret1 #注意ret後面不能加(),如添加():表示執行函數
else: print("請登入!!!") #及判斷登入和權限
def check_admin(func): def inner(*args,**kwargs): if USER_INFO.get('user_type',None)==2: #2表示超級管理員
ret2 = func(*args,**kwargs) #此時func爲原來index函數
return ret2 #此時ret2返回值傳輸給check_login裝飾器中的ret2
else: print("無權限查看") return inner #雙層裝飾器==》嵌套函數,裝飾器是從下往上解釋,執行是從上往下執行
@check_login #02 裝飾器接着把check_admin和(check_admin、index)當作一個參數傳遞給check_login下面inner函數
@check_admin #01 裝飾器把將check_admin和index當作一個參數傳遞給inner函數,
def index(): """ 管理員功能 :return: """
print('Index')
能夠加參數的裝飾器@filter(before,Agter),用於web程序dom
#!/usr/bin/env python #coding:utf-8 def Before(request,kargs): print 'before' def After(request,kargs): print 'after' def Filter(before_func,after_func): def outer(main_func): def wrapper(request,kargs): before_result = before_func(request,kargs) if(before_result != None): return before_result; main_result = main_func(request,kargs) if(main_result != None): return main_result; after_result = after_func(request,kargs) if(after_result != None): return after_result; return wrapper return outer @Filter(Before, After) def Index(request,kargs): print 'index'
Python中字符串格式化有兩種方式:%百分號方式、format方式
一、%百分號方式
%百分號方式相對而言比較老。而format方式則是比較先進的方式,Pyhton二者並存
百分號方式傳值方式:%[(name)][flags][width].[precision]typecode
name:可選,用於選擇指定的key
flags:可選,可選擇的值有
1)+:右對齊:正數前加正好,負數前加符號
#向右對齊且寬度爲10個字節
s = "i am %(name)+10s,%(age)d"%{'name':'lcj','age':123} #將字典中的元素按照key,value形式傳遞name,age
print(s)
2)-:左對齊:正數前無符號,負數前加符號
#向左對齊且寬度爲10個字節
s = "i am %(name)-10s,%(age)d"%{'name':'lcj','age':123} #將字典中的元素按照key,value形式傳遞name,age
print(s)
3)空格:右對齊:正數前加空格,負數前加負號
4)0:右對齊:正數前無符號,負數前加負號:用0填充空白處
typecode:選項
•s,獲取傳入對象的__str__方法的返回值,並將其格式化到指定位置 •r,獲取傳入對象的__repr__方法的返回值,並將其格式化到指定位置 •c,整數:將數字轉換成其unicode對應的值,10進制範圍爲 0 <= i <= 1114111(py27則只支持0-255);字符:將字符添加到指定位置 •o,將整數轉換成 八 進製表示,並將其格式化到指定位置 •x,將整數轉換成十六進制表示,並將其格式化到指定位置 •d,將整數、浮點數轉換成 十 進製表示,並將其格式化到指定位置 •e,將整數、浮點數轉換成科學計數法,並將其格式化到指定位置(小寫e) •E,將整數、浮點數轉換成科學計數法,並將其格式化到指定位置(大寫E) •f, 將整數、浮點數轉換成浮點數表示,並將其格式化到指定位置(默認保留小數點後6位) •F,同上 •g,自動調整將整數、浮點數轉換成 浮點型或科學計數法表示(超過6位數用科學計數法),並將其格式化到指定位置(若是是科學計數則是e;) •G,自動調整將整數、浮點數轉換成 浮點型或科學計數法表示(超過6位數用科學計數法),並將其格式化到指定位置(若是是科學計數則是E;) •%,當字符串中存在格式化標誌時(即存在%佔位符時),須要用 %%表示一個百分號 注:Python中百分號格式化是不存在自動將整數轉換成二進制表示的方式
經常使用格式化:
#將元素傳遞給佔位符
n1 = "i am is %s" %"lcj" print(n1) #將元祖中的元祖依次傳遞給佔位符%s %d
n2 = "i am %s age %d"%("lcj",18) print(n2) #將字典中的每個元素指定傳遞給佔位符
n3 = "i am %(name)s age%(age)d"%{"name":"lcj","age":18} print(n3) #取小數點前2位並按照四捨五入取值
n4 = "percent %.2f"%99.885 print(n4) #定點取小數
n5 = "i am %(pp).2f"%{"pp":123.45621,} print(n5) # n6 = "i am %.2f %%"%{"pp":123.4732,} print(n6) #c:將數字轉換至unicode對應的值,10進制範圍爲0<=i<=114111(py27則只支持0-255),字符:將字符添加至指定位置
n7 = "lcj %c----%o----%x---%e"%(65,15,15,1000000000) print(n7) n8 = "lcj %" print(n8) #在格式化字符串中,出現佔位符(%s %d %f),那麼須要用了兩個%%號輸出時表示一個%號(轉移效果)
n9 ="name %s %%"%("lcj") print(n9)
順序傳值:
s = "i am name %s,age %d"%('lcj',123) #lcj傳遞給name,123傳遞給age print(s)
指定元素進行傳值:
#指定傳值
s = "i am %(name)s,%(age)d"%{'name':'lcj','age':123} #將字典中的元素按照key,value形式傳遞name,age
print(s)
二、format方式
格式:[[fill]align][sign][#][0][width][,][.precision][type]
#基本格式化 n1 = "l---{0}----c-{0}---j--{1}".format(123,'xialuo') print(n1) #指定傳值將字符串傳給s,數字傳給d n2 = "i am--name-{name:s}--age-{age:d}".format(name="xiaoluo",age=19) print(n2) #":"冒號前加參數,則是按照命名方式進行傳值,如不添加參數,則順序傳值 n3 = "{:*^23s}===".format("clj") print(n3) #^內容居中,<:內容向左對齊,打印元素「*」只能用一個字符代替,不能用數據替換 n4 = "{:*<23s}===".format("clj") print(n4) #^內容居中,>:內容向右對齊(默認),打印元素「*」只能用一個字符代替,不能用數據替換 n5 = "{:*>23s}===".format("clj") print(n5) #^內容居中,= # n6 = "{:*=23s}===".format("clj") # print(n6) #format中單個%表示百分符號即把傳遞參數向前進2位並保留小數位 n7 = "---{:%}".format(0.33333) print(n7) #保留小數點前兩位 n8 = "---{:.2%}".format(0.33333) print(n8)
•傳入」 字符串類型 「的參數 •s,格式化字符串類型數據 •空白,未指定類型,則默認是None,同s •傳入「 整數類型 」的參數 •b,將10進制整數自動轉換成2進製表示而後格式化【%則不支持】 •c,將10進制整數自動轉換爲其對應的unicode字符 •d,十進制整數 •o,將10進制整數自動轉換成8進製表示而後格式化; •x,將10進制整數自動轉換成16進製表示而後格式化(小寫x) •X,將10進制整數自動轉換成16進製表示而後格式化(大寫X) •傳入「 浮點型或小數類型 」的參數 •e, 轉換爲科學計數法(小寫e)表示,而後格式化; •E, 轉換爲科學計數法(大寫E)表示,而後格式化; •f , 轉換爲浮點型(默認小數點後保留6位)表示,而後格式化; •F, 轉換爲浮點型(默認小數點後保留6位)表示,而後格式化; •g, 自動在e和f中切換 •G, 自動在E和F中切換 •%,顯示百分比(默認顯示小數點後6位)【在%字符串中:單個%表示佔位符,而在format中單個%號。則將數字轉換爲%比的形式】
經常使用格式化:
#format順序傳值給站位符{}
n1 = "i am {},age{},{}".format("lcj",15,'yxy') print(n1) #將列表中的每個元素順序添加至佔位符中,若是列表前不添加*號,則把列表中全部元素當作一個元素進行傳值
n2 = "i am {},age{},{}".format(*["lcj",18,'yxy']) print(n2) #按照索引方式進行傳值
n3 = "i am {0},age{1},really{0}".format("lcj",13) print(n3) #將列表中的元素按照索引方式進行傳值
n4 = "i am {0},age{1},really{0}".format(*["lcj",13]) print(n4) #指定參數進行傳值
n5 = "i am {name},age{age},really{age}".format(name="lcj",age = 12) print(n5) #將字典中元素指定傳值【傳字典須要在字典前面添加兩個**】
n6 = "i am {name},age{age},really{name}".format(**{"name":"lcj","age":12}) print(n6) #按照索引中索引進行傳值:0-》表示第一個列表,第二個0:》表示取第一個列表中的第一個元素
n7= "i am {0[0]},age{0[1]},really{0[2]}".format([1,2,3,],[4,5,6,]) print(n7) #依次給站位符傳遞「字符串」,「數字」,「浮點數」【:添加冒號則按照順序方式進行賦值,若是:號前面添加字符串,則按照定位方式進行傳值】
n8 = "i am {:s},age{:d},really{:.2f}".format("lcj",19,19.823) print(n8) #將列表中各元素按照字符串和數字依次進行傳遞,參數傳遞給%s %d的位置要一致【將列表中元素進行傳遞,則在列表前添加一個*】
n9 = "i am {:s},age{:d}".format(*["lcj",19]) print(n9) #給佔位符s,d指定參數
n10 = "i am {name:s},age{age:d}".format(name='lcj',age=20) print(n10) #給佔位符按照字典方式進行傳值
n11 = "i am {name:s},age{age:d}".format(**{"name":"xiaoluo","age":19}) print(n11) #把傳遞參數按照「b:二進制,o:八進制,d:十進制,x:十六機制」方式進行傳給佔位符
n12 = "number:{:b},{:o},{:d},{:x},{:X}".format(15,15,15,15,15,15.876,12) print(n12) #按照下標對佔位符進行傳值
n13 = "number:{0:b},{0:o},{0:d},{0:x},{0:X}".format(16) print(n13) #給站位符指定參數進行傳值
n14 = "number:{num:b},{num:o},{num:d},{num:x},{num:X},{num:%}".format(num=17) print(14)
[更多操做格式更多格式化操做:https://docs.python.org/3/library/string.html]
format佔位符號爲:{}
%百分號於format之間的區別?
1)format支持二進制方式【d:將10進制整數自動轉換成2進製表示而後格式化】,%百分號則不支持
2)format中的單個%,表示將數字轉換至百分比的形式
#format中單個%表示百分符號即把傳遞參數向前進2位並保留小數位
n7 = "---{:%}".format(0.33333) print(n7) #保留小數點前兩位
n8 = "---{:.2%}".format(0.33333) print(n8)
python中有兩個模塊序列化方式:
json:用於字符串和python基本數據類型之間的轉換
pickle:用於python特定的類型和python基本數據類型之間的轉換
一、json
經常使用的元素:dumps、dump,loads、load
dumps:將python基本數子格式轉化至字符串
loads:將字符串格式轉換至python基本數子格式
序列化
反序列化:
#json.loads [使用loads進行反序列化時,基本數字必須用雙引號]
import json #將python中字符串形式轉化成基本數據類型
s1 = '{"name":"lcj"}' ret = json.loads(s1) print(ret,type(ret))
dump:把python基本數據類型轉化爲字符串形式,並把轉化的字符串寫入文件
load:把字符串形式的數據轉化python基本數據類型,並從文件中讀取出來
import json #將基本數據類型轉換字符串形式, 並存入文件
li = {"name":"lcj"} ret = json.dump(li,open("db",'w+')) print(ret,type(ret)) #打開文件,並將python中文件字符存轉換至基本數據類型,
li =json.load(open('db','r')) print(li)
二、pickle
pickle序列化只適合用於python,其餘語言不能調用,json則是任何語言都一個調用或交互
經常使用的元素:dumps、dump,loads、load
json與pickle之間對比:
A:json:更加適合跨語言,字符串、基本數據類型
B:pickle:python中複雜類型的序列化,缺點:僅適用於Python(python各版本之間各有差別)
import pickle
#將python基本數據類型轉化爲字符串形式
li =[22,33,44,55,]
ret = pickle.dump(li,open("test.txt",'wb')) #將列表中的元素,按照本身方式寫入文件
print(ret,type(ret))
#按照字節方式將文件中的字符串形式轉化至列表
ret = pickle.load(open("test.txt",'rb'))
print(ret,type(ret))
什麼是模塊呢?
簡單的來講模塊代買實現了某一個功能的代碼集合。
相似於函數編程和麪向對象過程編程,函數式編程則完成一個功能,ITA代碼用來調用便可,提供了代碼的重用性和代碼間的耦合,二對對於一個複雜的功能來可能須要多個模塊函數才能完成(函數便可在不用的.py模塊中),n個.py文件組成的代碼集合就稱爲模塊。
一、模塊分爲三類:
1)、內置模塊
python內置模塊含:
A:sys模塊:
用於提供python解釋器相關的操做:
sys.argv 命令行參數List,第一個元素是程序自己路徑
sys.exit(n) 退出程序,正常退出時exit(0)
sys.version 獲取Python解釋程序的版本信息
sys.maxint 最大的Int值
sys.path 返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值
sys.platform 返回操做系統平臺名稱
sys.stdin 輸入相關
sys.stdout 輸出相關
sys.stderror 錯誤相關
B:os模塊
用於提供對Python解釋器相關的操做:
os.getcwd() 獲取當前工做目錄,即當前python腳本工做的目錄路徑
os.chdir("dirname") 改變當前腳本工做目錄;至關於shell下cd
os.curdir 返回當前目錄: ('.')
os.pardir 獲取當前目錄的父目錄字符串名:('..')
os.makedirs('dirname1/dirname2') 可生成多層遞歸目錄
os.removedirs('dirname1') 若目錄爲空,則刪除,並遞歸到上一級目錄,如若也爲空,則刪除,依此類推
os.mkdir('dirname') 生成單級目錄;至關於shell中mkdir dirname
os.rmdir('dirname') 刪除單級空目錄,若目錄不爲空則沒法刪除,報錯;至關於shell中rmdir dirname
os.listdir('dirname') 列出指定目錄下的全部文件和子目錄,包括隱藏文件,並以列表方式打印
os.remove() 刪除一個文件
os.rename("oldname","newname") 重命名文件/目錄
os.stat('path/filename') 獲取文件/目錄信息
os.sep 輸出操做系統特定的路徑分隔符,win下爲"\\",Linux下爲"/"
os.linesep 輸出當前平臺使用的行終止符,win下爲"\t\n",Linux下爲"\n"
os.pathsep 輸出用於分割文件路徑的字符串(分號分割)
os.name 輸出字符串指示當前使用平臺。win->'nt'; Linux->'posix'
os.system("bash command") 運行shell命令,直接顯示
os.environ 獲取系統環境變量
os.path.abspath(path) 返回path規範化的絕對路徑
os.path.split(path) 將path分割成目錄和文件名二元組返回
os.path.dirname(path) 返回path的目錄。其實就是os.path.split(path)的第一個元素
os.path.basename(path) 返回path最後的文件名。如何path以/或\結尾,那麼就會返回空值。即os.path.split(path)的第二個元素
os.path.exists(path) 若是path存在,返回True;若是path不存在,返回False
os.path.isabs(path) 若是path是絕對路徑,返回True
os.path.isfile(path) 若是path是一個存在的文件,返回True。不然返回False
os.path.isdir(path) 若是path是一個存在的目錄,則返回True。不然返回False
os.path.join(path1[, path2[, ...]]) 將多個路徑組合後返回,第一個絕對路徑以前的參數將被忽略
os.path.getatime(path) 返回path所指向的文件或者目錄的最後存取時間
os.path.getmtime(path) 返回path所指向的文件或者目錄的最後修改時間
獲取os模塊中獲取文件路徑:
__file__:
abspath獲取當前文件的絕對路徑
s.path.dirname找到某個文件上級目錄
import os import sys print(os.path.abspath(__file__)) #abspath獲取當前文件的絕對路徑 ret = os.path.dirname(os.path.abspath(__file__)) #os.path.dirname找到某個文件上級目錄 print(ret) ret = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #獲取當前文件夾上上級目錄位置 print(ret)
__package__
if __name == '__main__':
#只有執行當前文件時候,當前文件的特殊變量 __name == '__main__',不然不等於
#當前程序爲test.py def run(): print("run") run() #此時,run()函數可表示在任意導入模塊中導入test.py並可執行run()函數 def func(): print("func") if __name__ =='__main__': #當執行當前test.py程序時,此時的__name__就等於test.py func()
__doc__
含義:獲取當前註釋語句,無卵用
#view_bar:生成進度條
import sys import time #view_bar,生成進度條 def view_bar(num,total): rate = (num/total) raw_run = int(rate*100) # r = "\r%s>%d%%"%("="*num,raw_run) r = "\r%d%%"%(raw_run) ##\r:從新回到當前行首個位置,每次覆蓋前一個數字,字符串中含有佔位符須要兩個%%表示一個%號 # print(r) #prin():每次輸出換行 sys.stdout.write(r) #write:每次輸出不換行直接在一行打印輸出 sys.stdout.flush() #sys.stdout.flush:輸出清空 if __name__ == '__main__': for i in range(0,100): time.sleep(0.1) view_bar(i,100) #view_bar函數生成進度條,將i和100參數傳遞給view_bar函數
python2.7中進度條
import sys import time def view_bar(num, total): rate = float(num) / float(total) rate_num = int(rate * 100) r = '\r%d%%' % (rate_num, ) sys.stdout.write(r) sys.stdout.flush() if __name__ == '__main__': for i in range(0, 100): time.sleep(0.1) view_bar(i, 100)
C:random
import random
print(random.random()) #輸出0-1之間的小數
print(random.randint(1,8))#隨機輸出整數,整數範圍爲0-8之間的任意一個數字(左閉右閉)
print(random.randrange(1,9)) #隨機輸出整數,整數範圍在0-9之間隨機數(左閉右開)
例子:輸出6位數的字符+數字的驗證碼
import random checkcode = '' for i in range(6): #循環次數 current = random.randrange(0,6) #隨機輸出整數,位數在0-6之間 if current != i: #若是迭代次數不等於循環次數不等,則輸出65-90在asill中對應的字母 temp = chr(random.randint(65,90)) else: #不然,輸出0-9任意一個整數數字 temp =random.randint(0,9) checkcode += str(temp) # print(checkcode)
import random li= [] #將新生成的數據放至列表中 for i in range(6): #一共循環6次 r = random.randrange(0,5) #循環範圍在0-5之間,當循環數字爲2或者爲4時,就把打印(0-9)數字賦值給num if r == 2 or r == 4: num = random.randrange(0,10) li.append(str(num)) #輸出是列表的類型須要統一,0-9爲數字,65-91是將數據轉換至字母 else: temp = random.randrange(65,91)#accill中65-91相對應的數字母 c=chr(temp) li.append(c) #將生成數據賦值給li列表 s = "".join(li) #join把生成的字母拼接 print(s)
2)、自定義模塊
3)、第三方模塊
安裝第三方模塊方式有兩種:
1)pip3安裝 :pip3 install requests
2)源碼安裝:進入源碼安裝路徑,執行python setup.py install
注意:當pip沒法安裝時:
python中requests模塊安裝方式:(用於http請求時用到模塊)
A:python3可用:pip3 install requests
使用requests模塊:
無參數:
#無參數下
import requests import json requests = requests.get('http://wthrcdn.etouch.cn/weather_mini?city=北京') requests.encoding = 'utf-8' dic =json.loads(requests.text) #requests獲取天氣預報信息
print(dic,type(dic)) #將獲取信息轉換至一個字典形式
print(dic,list(dic)) #有參數下
import requests payload = {'key1': 'value1', 'key2': 'value2'} ret = requests.get("http://httpbin.org/get", params=payload) print(ret.url) print(ret.text)
導入模塊依據:import sys
導入模塊即便告訴Python解釋器其解釋那個py文件
1)導入一個py文件,解釋器解釋py文件
2)導入一個包,解釋器解釋該包下的_init_.py文件【Python2.7】
導入模塊路徑:
2、模塊的優勢:
A:進行代碼歸類
python查找腳本順序:首先在當前執行腳本的目錄下查找腳本,如找不到,則去python內置的路徑查找
模塊名稱重要性:
A:不能個python內置模塊名稱同樣,不然出錯
到入模塊方式有:
A:import +模塊名
B:from(去某個模塊帶入某個函數)【form s4 import login -->去S4模塊導入login函數】
C:在不一樣模塊中導入相同函數時,能夠給導入函數取別名
列如:
D:在單模塊下推薦:import導入模塊
在嵌套文件夾中推薦:from XX import xxx 或者給導入模塊取別名
一、迭代器:
迭代器是訪問集合元素的一種方式,迭代器對象是從集合的第一個元素開始訪問,直到全部的元素被訪問完才結束。迭代器只向前訪問不會後退。
迭代器特色:不要求是先準備好整個迭代過程當中的全部的元素,迭代器僅僅在迭代到某一個元素時才計算該元素,而在這以前以後,元素不存在,適用於遍歷一些巨大的或是無限的集合,如幾個G的文件
A:反問者不須要關係迭代器內部的結構,僅需經過_next_()方法不斷去取下一個內容
B:不能隨機訪問集合中的某個值,只能從頭至尾一次訪問
C:訪問到一半時不能往回退
D:便於循環比較大的數據集合,節省內存
#生成器標誌:yield,使用函數建立
def func(): print(111) yield 1
print(2222) yield 2
print(33333) yield 3 ret = func() r1=ret.__next__()#進入函數找到yield,獲取yield後面的數據
print(r1) r2=ret.__next__()#進入函數找到yield,獲取yield後面的數據
print(r2) r3=ret.__next__()#進入函數找到yield,獲取yield後面的數據
print(r3)
二、生成器
一個函數調用時返回一個迭代器,那麼這個函數叫作生成器(generator);如何函數中包含yield語法,那麼這個函數就會變成生成器
def func(): print(111) yield 1 #yield表示生成器標識 print(2222) yield 2 print(33333) yield 3
#下面是迭代器 ret = func() r1 = ret.__next__() #進入函數找到yield,並獲取yield後面的數據 print(r1) #1 r2 = ret.__next__() #進入函數找到yield,並獲取yield後面的數據 print(r2) #2 r3 = ret.__next__() #進入函數找到yield,並獲取yield後面的數據 print(r3) #3
例子:
def hhh(arg): start = 0 #設置初始值 while True: if start > arg: #當循環次數大於3次則結束 break yield start #獲取生成器數據 start +=1 #每次循環一次自增長一 ret = hhh(3) #將參數三次傳遞給arg,限定函數循環次數, r1 = ret.__next__() print(r1) #0 r2 = ret.__next__() print(r2) #1 r3 = ret.__next__() print(r3) #2 r4 = ret.__next__() print(r4) #3 r5 = ret.__next__() #這次已超過規定的次數 print(r5)
什麼是遞歸函數?
若是函數包含了對其自身的調用,那麼該函數就是遞歸函數
def d(): return 'lcj'
def c(): r=d() return r def b(): r=c() return r def a(): r=b() print(r) a() def func(n): n += 1
if n >=4: #當遞歸參數大於等於4,則返回end,不然繼續
return 'end'
return func(n) ret =func(0) print(ret)
練習例子:
實現階乘:1*2*3*4*5*6*7
def func(num):# if num == 1: #將參數爲1時結束 return 1 #將參數傳給num,7*func(7-1),那麼func(6)從新將6參數傳給func(num) return num*func(num-1) x = func(7) #將參數7傳給func(num) print(x)
遞歸官方解釋
(1)遞歸就是在過程或函數裏調用自身;
(2)在使用遞歸策略時,必須有一個明確的遞歸結束條件,稱爲遞歸出口。
#要求:
#遞歸算法所體現的「重複」通常有三個要求:
A:每次調用在規模上都全部縮小(一般減半)
B:相鄰兩次重複之間緊密的聯繫,前一次要爲後一次作準備(一般前一次的輸出就做爲後一次的輸入)
C:在問題規模極小時必須用直接出答案而再也不進行遞歸調用,於是每次遞歸調用都是有條件的
【無條件遞歸將會成爲死循環而再也不正常結束】
遞歸算法通常用於解決三類問題:
(1)數據的定義是按遞歸定義的。(好比Fibonacci函數)
(2)問題解法按遞歸算法實現。(回溯)
(3)數據的結構形式是按遞歸定義的。(好比樹的遍歷,圖的搜索)
遞歸的缺點:遞歸算法解題的運行效率較低。在遞歸調用的過程中系統爲每一層的返回點、局部量等開闢了棧來存儲。遞歸次數過多容易形成棧溢出等。
參考:http://www.cnblogs.com/balian/archive/2011/02/11/1951054.html
時間相關的操做,時間含有三張表示方式:
一、time模塊
import time
#打印時間戳
print(time.time())#返回值爲:1465439178.2469485 unix上線至今秒
#輸出當前系統時間
print(time.localtime())
#將時間戳轉換至struct_time格式
print(time.gmtime(time.time()))
#截取指定時間段
time_obj = time.gmtime()
print(time_obj)
print("{year}-{month}".format(year=time_obj.tm_year,month=time_obj.tm_mon))
#將時間戳轉換至struct_time格式,並返回本地時間
print(time.localtime(time.time()))
#與time.localtime()功能相反,將struct_time格式轉換至時間戳格式
print(time.mktime(time.localtime()))
#將struct_time時間對象轉成一個指定的時間格式:年月日時分秒
print(time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime())) #gmtime:轉換至格林尼治標準時間
#將字符串格式轉換成struct_time格式:
k = time.strptime("2016-06-09","%Y-%m-%d")
print(k)
print("---------------")
#將一個字符串格式的時間轉換至一個時間戳
k = time.strptime("2016-06-09","%Y-%m-%d")
print(time.mktime(k))
%Y Year with century as a decimal number.
%m Month as a decimal number [01,12].
%d Day of the month as a decimal number [01,31].
%H Hour (24-hour clock) as a decimal number [00,23].
%M Minute as a decimal number [00,59].
%S Second as a decimal number [00,61].
%z Time zone offset from UTC.
%a Locale's abbreviated weekday name.
%A Locale's full weekday name.
%b Locale's abbreviated month name.
%B Locale's full month name.
%c Locale's appropriate date and time representation.
%I Hour (12-hour clock) as a decimal number [01,12].
%p Locale's equivalent of either AM or PM.
二、datetime模塊
import datetime
#將時間按照:2016-06-09輸出
print(datetime.date.today())
#輸出2016-01-26 19:04:30.335935
current_time = datetime.datetime.now()
print(current_time)
#將當前時間返回值struct_time格式
print(current_time.timetuple())
#將當時前時間加10天
print(datetime.datetime.now()+datetime.timedelta(days=10))
#將當時前時間減10天
print(datetime.datetime.now()-datetime.timedelta(days=10))
#將當時前時間加10小時
print(datetime.datetime.now()-datetime.timedelta(hours=10))
#將當時前時間減10小時
print(datetime.datetime.now()-datetime.timedelta(hours=10))
#將當前時間返回值指定時間
# print(current_time.replace(2014,09))
判斷時間大小:
#時間大小判斷
kk = datetime.datetime.now() #答應當時間
print(kk)
print("-----------")
ww = kk.replace(2015,9) #將當前時間返回至201509
print(ww)
print("=====")
print(kk==ww) #如返回值是True,則兩個時間相等,False:則不等
logging模塊:
日誌模塊:python提供了標準的日誌接口,經常使用日誌級別有:debug(),info(),waring(),error() 和critical()五個級別。
日誌級別大小:DEBUG()<INFO()<WARING()<ERROR()<CRITICAL()
將日誌信息打印至文件:
import logging
#把日誌級別info以上的日誌信息存入example.log文件中
# logging.basicConfig(filename='example.log',level=logging.INFO)
#添加日誌打印時間輸出:按照月,天,年,時、分、秒輸出,asctime佔位符
logging.basicConfig(filename='example.log',level=logging.INFO,
format='%(asctime)s %(message)s',datefmt='%m/%d/%Y %I:%M:%S %p') #按照format將字符串進行拼接
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')
%(asctime)s:時間
%(filename)s:將程序文件名寫入日誌文件中
%(lineno)d:顯示日誌行號
%(module)s:模塊名
%(msecs)d:毫秒
%(pathname)s:路徑
%(process)d:進程號
%(processName):進程名
%(thread)d:線程
日誌輸出格式詳細地址:http://images2015.cnblogs.com/blog/425762/201605/425762-20160524044013866-178249755.png
import logging
#create logger
logger = logging.getLogger('TEST-LOG')#先獲取logger對象
logger.setLevel(logging.DEBUG) #設置一個全局日誌級別爲debug,那麼在往屏幕和文件輸出日誌時,不該比全局定義額日誌級別低
# create console handler and set level to debug #handler輸出至屏幕或則文件
ch = logging.StreamHandler() #把日誌輸出至屏幕 waring
ch.setLevel(logging.DEBUG) #把debug及超過bebug級別以上的日誌信息,輸出至屏幕
# create file handler and set level to warning
fh = logging.FileHandler("access.log") #把日誌輸出至文件
fh.setLevel(logging.WARNING) #把warning及超過warning級別以上的日誌信息,輸出至文件
fh_error = logging.FileHandler("error.log") #將出報錯信息,打印至error.log文件
fh_error.setLevel(logging.ERROR) #設置錯誤信息級別爲ERROR
# create formatter 建立日誌輸出格式 %(asctime)s:時間 %(filename)s:將程序文件名寫入日誌文件中
# %(lineno)d:顯示日誌行號 %(module)s:模塊名 %(msecs)d:毫秒,%(pathname)s:路徑,%(process)d:進程號
# %(processName):進程名 ,%(thread)d:線程
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(filename)s - %(lineno)s - %(thread)d - %(message)s')
formatter_for_file = logging.Formatter('%(asctime)s - %(filename)s - %(lineno)s - %(name)s - %(levelname)s - %(message)s')
# add formatter to ch and fh
ch.setFormatter(formatter) #ch屏幕
fh.setFormatter(formatter) #fh文件
fh_error.setFormatter(formatter) #fh文件
# add ch and fh to logger 定義日誌輸出的地方
logger.addHandler(ch) #指定日信息打印至屏幕
logger.addHandler(fh) #指定日信息打印至文件
logger.addHandler(fh_error) #指定日信息打印至文件
# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')
繼續完善中、、、、、
本節做業
做業需求:
模擬實現一個ATM + 購物商城程序