#!/usr/bin/env python # -*- coding:utf-8 -*- #筆記大綱 #1.函數對象(內存中的地址或映射),能夠當作數據傳遞 #函數對象能夠被調用 # def foo(): # print("this is a test") # # foo1 = foo #把函數對象賦值給一個變量 # foo1() #---->foo()函數執行 #能夠當作參數傳遞 # def foo1(args): #此處args的是foo2函數對象 # print(args) # args() #------>foo2()函數的調用 # # def foo2(): # print("this is foo2") # # foo1(foo2) #---->把foo2函數對象當作參數傳遞給foo1,最後實質是先print,而後args()--->foo2() #返回值能夠是函數 # def foo(): # print('from foo') # # def bar(func): # return func #--->返回傳入函數對象 # # f=bar(foo) #---->把foo函數對象傳入bar函數賦值給變量f,f實質仍是foo函數對象,f()調用函數執行的是foo() # # print(f) #---->打印的是foo函數對象 # # f() #---->foo() #能夠當作容器類型的元素 # def andy(): # print("this is andy") # # def yang(): # print("this is yang") # # test_l = { # "andy":andy, #--->此處andy是函數對象 # "yang":yang, #--->此處yang是函數對象 # } # # while True: # chei = input(">> ").strip() # if chei in test_l: # test_l[chei]() #---->此處是經過字典的鍵取到對應的函數對象,而後加上()調用 # else: # break #2.函數的嵌套 # def foo5(): # def foo6(): # print("this is foo6") # def foo7(): # print("this is foo7") # foo7() # foo6() # # foo5() #正常 #foo6() #此處報錯,foo6()爲內部函數只能在函數內部使用,當函數執行完成即銷燬 #3.名稱空間和做用域 #名稱空間(定義名字的方法,名稱到對象的映射,這就像是字典,鍵名是變量名,值是變量的值) import time # name = 'andy' # def func(): # pass # class Foo(): # pass #名稱空間的分類 #1.內置名稱空間:隨着python的解釋器的啓動而啓動 # print(sum) # # import builtins # for i in dir(builtins): #查看內置名稱空間 # print(i) #2.全局名稱空間:文件的執行會產生全局名稱空間,指的是文件級別定義的名字都會放入該空間 # x=1 #全局名稱空間 # def func(): # money=2000 #---->局部名稱空間 # x=2 #---->局部名稱空間 # print('func') # print(locals()) #---->{'x': 2, 'money': 2000}局部名稱空間名字 # print(x) # print(func) # # print(money) # # func() # print(x) # # #print(globals()) === print(locals()) #由於全局名稱空間對於它自己來講也是一個局部,所以此處打印全局名稱空間和局部名稱空間是同樣的 #局部名稱空間:調用函數時會產生局部名稱空間,只在函數調用時臨時綁定,調用時結束 # x=10000 # def func(): # x=1 # def f1(): # print("this is %d" %(x)) # f1() # func() #---->legb規則(locals -> enclosing function -> globals -> __builtins__) # # print(x) #---->輸出10000,由於x=1是局部名稱空間,因此在函數執行完成以後,就銷燬 #做用域 #全局做用域:內置名稱空間,全局名稱空間 #局部做用域:局部名稱空間 #全局做用域:全局有效,在任何位置都能被訪問到,除非del刪掉,不然會一直存活到文件執行完畢 #局部做用域的名字:局部有效,只能在局部範圍調用,只在函數調用時纔有效,調用結束就失效 #查看全局做用域內的名字:gloabls() #查看局局做用域內的名字:locals() # gx = 1000 #全局做用域的全局名稱空間 # def gfoo(): # gx = 2000 #局部做用域的局部名稱空間,函數執行完則銷燬 # def lfoo(): # print(gx) # print(locals()) # # lfoo() # # print(locals()) #---->等於print(globals()) # gfoo() # print(gx) #4.閉包函數(惰性計算)(定義在函數內部,包含對外部做用域而非全局做用域的引用) # def bibao(x): # def relb(): # z = x + 1 # return z # return relb #將這個局部函數對象返回,以便在全局做用域調用 # # ssg = bibao(4) #---->relb函數對象 # print(ssg()) # def bibao2(): # x = 5 # def bibao3(): # return x + 3 # return bibao3 # # sp = bibao2() # print(sp()) # from urllib.request import urlopen # def contr(url): # def wraper(): # conts = urlopen(url).read() # return conts # return wraper # # sycont = contr("http://www.baidu.com") # print(sycont().decode('utf-8')) #5.裝飾器函數(就是對閉包的一種實現,把裝飾器下面的函數當成參數傳遞,對已有函數添加新的功能,裝飾器自己能夠是任何可調用對象(加()能夠被執行),被裝飾的對象也能夠是任意可調用對象) import time from urllib.request import urlopen # def newb(func): # def newbi(): # start_time = time.time() # func() #--->index() # stop_time = time.time() # print("spent times: %s" %(stop_time-start_time)) # return newbi # # #@newb #--->index=newb(index) # def index(): # time.sleep(2) # print("welcome to my page") # # # index() #----->index=newbi # # f = newb(index) #---->f ==newbi函數對象,由於newb()執行返回的結果是newbi函數對象 # print(f) #----->f就是newbi函數對象 # f() #---->f()等於newbi() #被裝飾的函數有返回值 # def zhuangsq(func): # def fuck(*args,**kwargs): # stime = time.time() # news = func(*args,**kwargs) #----->yang() # etime = time.time() # print("spent times:%s" %(etime-stime)) # return news # return fuck # # @zhuangsq # def andy(): # time.sleep(2) # print("this is andy") # # @zhuangsq #--->yang=zhuangsq(yang)--->fuck函數對象 # def yang(name): # time.sleep(3) # print("this is yang") # # andy() # yang("zhangyou") # ---->fuck('zhangyou') # # def zhuans(func): # def wrapper(): # startime = time.time() # scont = func() # stoptime = time.time() # print("spent times: %s" %(stoptime-startime)) # print(scont) # return wrapper # # @zhuans # ---->geturl=zhuans(geturl) # def geturl(): # time.sleep(10) # sp = urlopen("http://www.baidu.com").readline() # return sp.decode('utf-8') # # geturl() #對已有函數添加用戶名和密碼認證功能 # userdb = { # "name":None, # "status":False # } # # # def auth(func): # def wrapper(*args,**kwargs): # if userdb["name"] and userdb["status"]: # res = func(*args,**kwargs) # return res # else: # name = input(">> ").strip() # password = input(">> ").strip() # if name == "andy" and password == "123": # userdb["name"]="andy" # userdb["status"]=True # res = func(*args, **kwargs) # return res # else: # print("login failed!") # return wrapper # # # @auth # def mypage(): # print("this is my homepage") # # @auth # def mainpage(name): # print("this is my mainpage %s" %(name)) # # mypage() # mainpage("andy") #有參裝飾器疊加 # userdb = { # "name":None, # "status":False # } # # def timer(func): # def newt(*args,**kwargs): # stime = time.time() # func(*args,**kwargs) # etime = time.time() # print("spent time:%s" %(etime-stime)) # return newt # # def choi(driver): # def auth(func): # def wrapper(*args,**kwargs): # if driver=="file": # if userdb["name"] and userdb["status"]: # res = func(*args,**kwargs) # return res # else: # name = input(">> ").strip() # password = input(">> ").strip() # if name == "andy" and password == "123": # userdb["name"]="andy" # userdb["status"]=True # res = func(*args, **kwargs) # return res # else: # print("login failed!") # elif driver=="mysql": # print("this is mysql auth") # else: # print("unkown auth") # return wrapper # return auth # # @timer # @choi("mysql") #--->auth---mypage = wrapper(mypage)--->index=wrapper # def mypage(): # print("this is my homepage") # @timer # @choi("file") # def mainpage(name): # print("this is my mainpage %s" %(name)) # # mypage() # mainpage("andy") #6.迭代器(內置__iter__方法的,都是可迭代的對象,執行__iter__方法獲得的結果就是迭代器,迭代器對象有__next__方法;對於沒有索引的數據類型,必須提供一種不依賴索引的迭代方式) # h = [1,2,3] # m = h.__iter__() # print(next(m)) # print(next(m)) # print(next(m)) # j = {"a":1,"b":2,"c":3} # n = iter(j) #此處n是迭代器 # print(n) # key = next(n) # print(j[key],key) # print(next(n)) # print(next(n)) #判斷數據類型是不是能夠被迭代或者是迭代器(文件是可迭代對象自己也是迭代器,對迭代器使用iter方法獲得的仍是迭代器自己) from collections import Iterable,Iterator # f=open('a.txt','w') # print(isinstance('abc',Iterable)) # print(isinstance([],Iterable)) # print(isinstance((),Iterable)) # print(isinstance({'a':1},Iterable)) # print(isinstance({1,2},Iterable)) # print(isinstance(f,Iterable)) # print(isinstance('abc',Iterator)) # print(isinstance([],Iterator)) # print(isinstance((),Iterator)) # print(isinstance({'a':1},Iterator)) # print(isinstance({1,2},Iterator)) # print(isinstance(f,Iterator)) #7.生成器函數(只要函數體包含yield關鍵字,該函數就是生成器函數,生成器也是迭代器,至關於yield爲函數封裝好了__iter__和__next__方法) # def foo12(): # print("first") # yield 1 # print("second") # yield 2 # print("third") # yield 3 # # hk = foo12() #此處hk是生成器對象 # for i in hk: # print(i) # print(next(hk)) # print(next(hk)) # print(next(hk)) #tail -f a.txt|grep "python" #定義2個生成器,一個用於輸出最後一行的內容,一個用於查找關鍵字 # def readt(name): # with open(name,"r",encoding='utf-8') as f: # f.seek(0,2) # while True: # m = f.readline().strip() # if m: # yield m # else: # time.sleep(0.2) # # # t = readt("a.txt") #--->生成生成器對象 # # # print(t) # # # # for line in t: # # print(line) # # def grep(pattern,lines): # for line in lines: # if pattern in line: # yield line # # # g=grep('python',readt('a.txt')) # # print(g) # for i in g: # print(i) #8.內置函數 # print(dir(__builtins__)) # # for h in dir(__builtins__): #查看內置函數的方法 # print(h) # # help(sum) #查看具體函數的幫助 #查看一個對象下面的屬性 # list_a = [] # print(dir(list_a)) #zip(將多個能夠迭代對象中的元素一一對應並生成元組) # s = "andy" # b = "1234" # t = "wesr" # z = zip(s,b,t) # for i in z: # print(i) #eval將字符串中的命令轉換出來執行 # dic="{'a':1,'b':2}" # d=eval(dic) # print(type(d),d['a'])