Zookeeper的應用-分散式鎖
阿新 • • 發佈:2020-11-22
- 函式也叫方法,比如你用手機打電話就是一個函式,你只管用就好,裡面的功能別人已經幫你研發好了,你只需要輸入手機號,按下撥打電話就好了,這個概念用在程式碼裡尤為重要,比如重複某個功能,比如使用者輸入,你要判斷使用者輸入,你要判斷使用者的輸入不能為空,那麼這個你可以定義一個函式,就是用來判斷使用者的輸入是否為空,每次呼叫一下就可以,假如現在校驗使用者輸入的需求變化了,那麼你直接維護這個函式就好了,沒必要再去所有的程式碼裡找這個校驗,一個個的去改,所有函式有以下兩個顯而易見的優點:
- 重複程式碼精簡,簡化複用性程式碼的編寫,將重複性程式碼寫成函式,要用的時候呼叫即可;
- 方便以後維護,你改一個函式,所有呼叫這個函式的地方的功能都能及時更新,避免修改程式碼遺漏
- 函式在前面的字串方法已經接觸過了,像strip()這些,就是python內建的一些函式,當然還有很多,這些函式python已經幫我們寫好了,直接用就好了,這樣是不是很方便,什麼時候需要什麼時候就呼叫。顯而易見,函式要呼叫的時候才會執行,呼叫函式就是在函式名後加()就可以呼叫了,像strip()這些。
- 函式初識
- 定義函式的時候,寫的入參叫形參;
- 呼叫函式的時候,傳的值叫實參;
-
1 def sayName(name,age,sex): #name,age,sex就是形式引數 2 # name,age,sex函式的引數型別是位置引數、必填引數 3 print('姓名:%s'%name) 4 print('年齡:%s'%age) 5 print('性別:%s'%sex) 6 #上面這個就是函式體 7 8 9 sayName('星星',18,'男') #'星星',18,'男'這三個就是實際引數,呼叫的時候傳進來的引數
- 函式ruturn
- 函式如果需要返回值,用return即可,有兩點需要注意:
- 函式裡,只要遇到return就結束,不會再往下執行
- 如果函式沒有指定return返回值,那麼函式預設返回的是None
-
1 def call(a,b): 2 return a+b 3 return a*b 4 def call2(a,b): 5 print('函式內a,b執行結果:',a+b) 6 7 print('call函式return結果:',call(1,2)) 8 print('call2函式return結果:',call2(1,2)) 9 10 #call函式return結果: 3 #因為函式裡return了a+b的結果,所以這裡的結果是3 11 #函式內a,b執行結果: 3 #這個是call2函式體裡執行的結果 12 #call2函式return結果: None #因為函式裡沒有return,所以這裡的結果是None
- 函式如果需要返回值,用return即可,有兩點需要注意:
- 函式即變數
- 之前接觸過變數,在記憶體裡開放一個地方存變數,函式也是一樣的,也是變數,存在記憶體裡的某個地方,呼叫直接就是函式名(),就呼叫了,看一個有趣的呼叫方法,先定義一個字典,value存函式名,根據key來呼叫相應的函式
-
1 def play(): 2 print('出去浪') 3 def study(): 4 print('好好學習') 5 def_method={'1':play,'2':study} 6 while True: 7 choice = input('請輸入你的選擇:1代表出去浪,2代表好好學習') 8 if choice =='1' or choice =='2': 9 def_method[choice]() 10 print(type(def_method[choice]())) 11 break 12 else: 13 print('請輸入正確的選擇') 14 continue
-
while True:是死迴圈,這裡只是寫一個迴圈,真實的工作場景中,需要填寫正確的條件判斷
-
- 之前接觸過變數,在記憶體裡開放一個地方存變數,函式也是一樣的,也是變數,存在記憶體裡的某個地方,呼叫直接就是函式名(),就呼叫了,看一個有趣的呼叫方法,先定義一個字典,value存函式名,根據key來呼叫相應的函式
- 入參型別
- 函式的入參有很多型別,上面已經瞭解過位置引數,還有預設引數,可變引數,關鍵字引數
- 注意引數有順序,如果上述四種引數你都有用,那麼引數型別順序必須是:位置引數 -> 預設引數 -> 可變引數-> 關鍵字引數,否則報錯
- 位置引數:這個引數就和格式化輸出裡的佔位一樣,形參先把位置站好,然後就等著使用者呼叫的時候輸入實參,排隊填坑,如果實參和形參個數不一致,多了或者少了都會報錯,如下:
1 def add(a,b): 2 print('%s+%s=%s'%(a,b,a+b)) 3 return a*b 4 add(1,2) #列印結果:1+2=3 5 add(6,2) #列印結果:6+2=8 6 add(1,2,3) #列印結果:報錯,引數多了 7 add(2) #列印結果:報錯,引數少了
- 這個引數就是程式會先給一個預設的,不傳不會報錯,會直接使用預設的這個引數值,如果傳了就用你傳的這個值;等於是定義函式的時候先定義了一個引數變數,呼叫的時候沒傳就用之前定義好的,如果傳了就是覆蓋之前的值,用傳入的引數值:
-
1 def multi(a,b=2): 2 print('%s**%s=%s'%(a,b,a**b)) 3 4 multi(3) #不傳參的時候預設b=2,這裡求的是平方 5 multi(4,3) #傳的時候b=3,這裡求的是立方 6 multi(2,b=4) #和上面的這個呼叫是一樣的,但是一般這樣寫,如果預設引數較多時,不會因為位置而出錯 7 multi(b=4,2) #報錯,位置引數必須在前(positional argument follows keyword argument)
- 可變引數:這裡一般用的少,可變就是引數是變化的,考慮到了程式的擴充套件性,定義函式的時候並不確定會有多少個引數,這裡就用到了可變引數,既然可變,那麼在呼叫函式的時候也是可以不輸入的:
-
1 # 可變引數 2 def user(name,passwd,*args): #一般是用args來命名的,當然也可以用其他你想要的名字 3 print('使用者名稱:%s,密碼:%s'%(name,passwd)) 4 print('還有如下屬性:\n',args) #這裡的args,就是使用者輸入引數的一個元祖 5 6 user('chenmeng',12334,'男','180cm','60kg') 7 # 列印結果: 8 # 使用者名稱:chenmeng,密碼:12334 9 # 還有如下屬性: 10 # ('男', '180cm', '60kg')
-
- 關鍵字引數,也不是必填的,他是一個key-value的字典形式:
-
1 # 關鍵字引數:也不是必填的,他是一個key-value的字典形式 2 def user(name,passwd,**args): 3 print('使用者名稱:%s,密碼:%s'%(name,passwd)) 4 print('還有如下屬性:\n',args) 5 user('xingxing',123456,sex='男',height='180cm') 6 # 列印結果: 7 # 使用者名稱:xingxing,密碼:123456 8 # 還有如下屬性: 9 # {'sex': '男', 'height': '180cm'}
-
- 位置引數:這個引數就和格式化輸出裡的佔位一樣,形參先把位置站好,然後就等著使用者呼叫的時候輸入實參,排隊填坑,如果實參和形參個數不一致,多了或者少了都會報錯,如下:
- 變數作用域
- 變數作用域有四種:全域性作用域,區域性作用域,內建作用域,閉包函式外的函式中,後兩者用的少,全域性作用域和區域性作用域概念用的多。全域性作用域就是變數在所有的範圍都可以用,比如在程式碼開始定義一個變數,那麼不論是在函式外部還是內部都可以用這個變數;區域性作用域就是隻能在某個區域內才能用,除了這個區域就用不了了,比如函式內定義的變數只能在函式體內用,出了函式就用不了 了。(建議不要使用全域性變數,不安全,所有人都可以修改)
- 全域性作用域
-
1 # 全域性作用域 2 hys=['螢幕','主機'] #全域性變數 3 def add(thing): 4 hys.append(thing) 5 add('麥克') 6 print(hys) #列印結果為:['螢幕', '主機', '麥克']
-
- 區域性作用域
-
1 # 區域性作用域 2 def add(thing): 3 desk=['顯示器','滑鼠'] #區域性變數 4 desk.append(thing) #函體內修改區域性變數 5 add(223) 6 print(desk) #函式體外呼叫區域性變數報錯
-
值得一提的是,當全域性變數是一個不可編輯的引數時,需要先申明才可以用全域性變數(str/int/float等不可變變數函式在呼叫全域性變數時,需要global才可以修改)
-
1 # 不可變變數的全域性變數引用,如int、float、str 2 money = 500 3 def chage(): 4 money=1000 5 print('函式內的money:',money) #列印結果是1000,因為函式內部作用域中money=1000,不能修改外面的money 6 chage() 7 print('函式外的money:',money) #列印結果為500,因為函式不可修改外部作用域中不可變變數的全域性變數引用,如int、float、str 8 9 def chage(): 10 global money #global後就可以引用了,這就聲明瞭money是一個全域性變數,函式內可以修改 11 money =1000 12 print('函式內的money:',money) #列印結果是1000 13 chage() 14 print('函式外的money:',money) #列印結果是1000,因為global聲明瞭全域性變數,所以可以修改
-
- 函式迭代,就是自己呼叫自己,一個死迴圈,一直呼叫下去,最多迭代999次,超過999次程式自動停止執行(while沒有次數限制)
- 啊
- 函式迭代
- 函式迭代,就是自己呼叫自己,一個死迴圈,一直呼叫下去,最多跌倒999次,超過999次程式自動停止執行(while沒有次數限制)。既然這樣,那麼迭代肯定要有一些特性才可以正常呼叫:
- 必須有一個明確的結束條件
- 每次進入更深一層遞迴時,問題規模相比上次遞迴都因有所減少
- 遞迴效率不高,遞迴層次過多會導致棧溢位(在計算機中,函式呼叫是通過棧(stack)這種資料結構實現的,每當進入一個函式呼叫,棧就會加一層棧幀,每當函式返回,棧就會減一層棧幀。由於棧的大小不是無限的,所以,遞迴呼叫的次數過多,會導致棧溢位)
-
1 # 函式迭代,就是自己呼叫自己,一個死迴圈,呼叫下去 2 def dd(): 3 print('學習學習努力學習') 4 dd() #函式內,又呼叫了函式本身,那麼就會一直呼叫下去 5 dd() #迭代函式最多會呼叫999次,這裡會列印999次'學習學習努力學習'
- 用函式迭代寫斐波拉契數列:[1, 1, 2, 3, 5, 8, 13, 21, 34],數列從第3項開始,每一項都等於前兩項之和。
- 先用之前的知識來寫
-
1 list=[] 2 def fb(num): 3 a=1 4 b=1 5 while num >0: 6 list.append(a) 7 a,b=b,a+b 8 print(b) 9 num-=1 10 fb(9) 11 print(list)
-
- 用迭代來寫
-
1 list=[] 2 a=1 3 b=1 4 def fb(num): 5 global a,b 6 list.append(a) 7 a,b=b,a+b 8 num-=1 9 if num>0: 10 fb(num) 11 12 fb(9) 13 print(list)
-
- 函式迭代,就是自己呼叫自己,一個死迴圈,一直呼叫下去,最多跌倒999次,超過999次程式自動停止執行(while沒有次數限制)。既然這樣,那麼迭代肯定要有一些特性才可以正常呼叫: