Python_Day_5裝飾器、字符串格式化、序列化、內置模塊、生成器、迭代器之篇

1、裝飾器

  爲何要用裝飾器???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")

 

2、雙層裝飾器

  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'

 

 2、字符串格式化

  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]

  •   fill:【可選】
  •   align:【可選】,對齊方式(需配合width寬度使用)
    • <:內容左對齊
    • >:內容右對齊(默認)
    • =,內容右對齊,將符號放置在填充字符的左側,且字符類型有效:符號+填充物+數字
    • ^ :居中
    • #基本格式化
      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)
    • # 【可選】添加#則對二進制、八進制、十進制、十六進制會顯示:0b/0o/0x,不添加則不顯示
    • , 【可選】:數字添加分隔符,如:1,000,000
    • width:【可選】格式化位所佔寬度
    • .precision 【可選】:保留小數點位數
    • type 【格式化類型】
•傳入」 字符串類型 「的參數 •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)

  3、序列化

  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)
View Code

   二、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))

 

3、python模塊

  什麼是模塊呢?

  簡單的來講模塊代買實現了某一個功能的代碼集合。

  相似於函數編程和麪向對象過程編程,函數式編程則完成一個功能,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)
View Code
 更多requests模塊相關的文檔見:http://cn.python-requests.org/zh_CN/latest/

   導入模塊依據: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 或者給導入模塊取別名 

4、生成器、迭代器

  一、迭代器:

  迭代器是訪問集合元素的一種方式,迭代器對象是從集合的第一個元素開始訪問,直到全部的元素被訪問完才結束。迭代器只向前訪問不會後退。

  迭代器特色:不要求是先準備好整個迭代過程當中的全部的元素,迭代器僅僅在迭代到某一個元素時才計算該元素,而在這以前以後,元素不存在,適用於遍歷一些巨大的或是無限的集合,如幾個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)
 

 

 

5、遞歸

  什麼是遞歸函數?

  若是函數包含了對其自身的調用,那麼該函數就是遞歸函數 

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

 6、time & timedate

  時間相關的操做,時間含有三張表示方式:

    • 時間戳  1970年1月1日以後的秒,即:time.time()
    • 格式化的字符串:2014-11-11 11:11 ,即:time.strftime('%Y-%m-%d')
    • 結構化時間:元組包含了,年,日,星期等...time.struct_time 即:timelocation()

  一、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 + 購物商城程序

  1. 額度 15000或自定義
  2. 實現購物商城,買東西加入 購物車,調用信用卡接口結帳
  3. 能夠提現,手續費5%
  4. 每個月22號出帳單,每個月10號爲還款日,過時未還,按欠款總額 萬分之5 每日計息
  5. 支持多帳戶登陸
  6. 支持帳戶間轉帳
  7. 記錄每個月平常消費流水
  8. 提供還款接口
  9. ATM記錄操做日誌
  10. 提供管理接口,包括添加帳戶、用戶額度,凍結帳戶等。。。
相關文章
相關標籤/搜索