做爲一個Python的初學者來講,深刻理解Python中函數的概念是一件重要的事情。python
重點1:如何理解函數是第一類對象(一等公民)
函數是第一類對象的概念:sql
第一:函數的名字是對函數的引用數據庫
第二:函數做爲第一類對象能夠賦值給其餘的變量async
第三:能夠做爲函數的參數傳遞給其餘的函數函數
第四:能夠做爲函數的返回值優化
第五:函數能夠做爲容器類型的一個元素ui
簡單來講,在python當中,函數能夠當作數據來進行傳遞,即變量有什麼特性,函數就有什麼特性。函數名字實際上就是一個指針變量,裏面存放着函數體內存空間的地址url
def foo(): """ 關鍵:foo就是C語言當中的指針變量,裏面存放着內存空間的地址 """ print('我愛吃大刀肉') print('我愛吃涮羊肉') print('我愛吃土豆肉') fun = foo print(fun,foo) #此時此刻fun和foo這兩個指針變量指向同一塊的內存空間 fun()
def foo(): """ 關鍵:foo就是C語言當中的指針變量,裏面存放着內存空間的地址 """ print('我愛吃大刀肉') print('我愛吃涮羊肉') print('我愛吃土豆肉') def g(func): #咱們將func做爲一個函數的參數進行傳遞 print(func) func() g(foo)
def foo(): """ 關鍵:foo就是C語言當中的指針變量,裏面存放着內存空間的地址 """ print('我愛吃大刀肉') print('我愛吃涮羊肉') print('我愛吃土豆肉') def g(func): #咱們將func做爲函數的返回值進行使用 print(func) return func f = g(foo) print(f) f()
接下來咱們將對最後一個進行深刻講解:spa
示例1:普通版程序指針
def select(sql): print('=========>select') def insert(sql): print('=========>insert') def update(sql): print('=========>update') def delete(sql): print('=========>delete') if __name__ == '__main__': while True: sql = input('>>').strip() if not sql:continue l = sql.split() cmd = l[0] if cmd == 'select': select(sql) elif cmd == 'insert': insert(sql) elif cmd == 'update': update(sql) elif cmd == 'delete': delete(sql) else: pass
上面的這個程序看似沒有什麼問題,可是若是有20個類型的話,難道你要寫20個if....else...嗎?
修改版:
def select(sql): print('=========>select') def insert(sql): print('=========>insert') def update(sql): print('=========>update') def delete(sql): print('=========>delete') if __name__ == '__main__': #做爲第一類對象,函數能夠做爲容器類型的元素 dict_func = { 'select':select, 'insert':insert, 'update':update, 'delete':delete, } while True: sql = input('>>').strip() if not sql:continue l = sql.split() cmd = l[0] if cmd in dict_func: dict_func[cmd](sql)
通過上面一折騰,是否是代碼上升了一個檔次。
實際業務版:普通版程序
def handle_async(tag_id,tag_type): """ :param tag_id: DDL id :param tag_type: 具體類型 content:if...else...後續這裏要繼續優化 """ if '數據庫自助化上線' in tag_type: handle_service(tag_id,tag_type) elif '普通上線申請流程' in tag_type: handle_common(tag_id, tag_type) elif '空庫初始化' in tag_type: handle_empty(tag_id, tag_type) elif 'DBChange確認流程' in tag_type: handle_dbchange(tag_id, tag_type) elif 'DDL變動申請流程' in tag_type: handle_ddl(tag_id, tag_type) else: pass
改進版:
def handle_async(tag_id,tag_type): dict_func = { '數據庫自助化上線':handle_service, '普通上線申請流程':handle_common, '空庫初始化':handle_empty, 'DBChange確認流程':handle_dbchange, 'DDL變動申請流程':handle_ddl, } for key in dict_func: if key in tag_type: dict_func[key](tag_id,tag_type)
後來由於代碼我又改了一次:普通版以下
def handle_async(tag_id,tag_type): """ :param tag_id: DDL id :param tag_type: 具體類型 content:if...else...後續這裏要繼續優化 """ if '數據庫自助化上線' in tag_type: url = url_list['service'] + tag_id handle_service(tag_id,tag_type,url=url) elif '普通上線申請流程' in tag_type: url = url_list['common'] + tag_id handle_common(tag_id, tag_type,url=url) elif '空庫初始化' in tag_type: url = url_list['empty'] + tag_id handle_empty(tag_id, tag_type,url=url) elif 'DBChange確認流程' in tag_type: handle_dbchange(tag_id, tag_type) elif 'DDL變動申請流程' in tag_type: url = url_list['ddl'] + tag_id handle_ddl(tag_id, tag_type,url=url) else: pass
改進版以下:
def handle_async(tag_id,tag_type): dict_func = { '數據庫自助化上線':['service',handle_service], '普通上線申請流程':['common',handle_common], '空庫初始化':['empty',handle_empty], 'DBChange確認流程':['dbchange',handle_dbchange], 'DDL變動申請流程':['ddl',handle_ddl], } for key,value in dict_func.items(): if key in tag_type: url = url_list[item[0]]+tag_id item[1](tag_id,tag_type,url=url)
OK,基本上就是這麼一個套路。
重點2:函數的嵌套
函數嵌套調用和嵌套定義的概念:
函數的嵌套調用:在一個函數的內部調用另一個函數,叫作函數的嵌套調用
函數的嵌套定義:在一個函數的內部定義另一個函數,叫作函數的嵌套定義
示例程序1:
def max2(x1,x2): max_value = x1 if x1 > x2 else x2 return max_value def max4(x1,x2,x3,x4): x12 = max2(x1,x2) x34 = max2(x3,x4) max_value = x12 if x12 > x34 else x34 return max_value print(max4(130,20,30,40))
示例程序2:
def fun1(): """ contention:函數的定義至關於變量的定義,是沒有任何實際打印效果的 """ print('大刀肉....') def fun2(): print('涮羊肉....') def fun3(): print('土豆肉....') fun3() fun2() fun1()
重點3:Python中名稱空間與做用域的概念
在python當中,名稱空間與做用域是一個比較難理解的概念,但願在這裏給你們講清楚。
名稱空間與做用域的概念:
名稱空間:描述的就是名字與數值的綁定關係,能夠理解爲存放名字(標識符)的地方;做用域:名字起做用的區域,範圍
注意:
一、名稱空間與名稱空間彼此之間是互相隔離的
二、不一樣namespace的建立/銷燬時間也不一樣
三、兩個不一樣namespace中的兩個相同名字的變量之間沒有任何聯繫
Python中名稱空間的分類:
在Python當中,名稱空間分爲3種:局部名稱空間(locals)、全局名稱空間(globals)和內置名稱空間(builtins)
局部名稱空間:即在函數內部定義的名稱空間,包括局部變量和形式參數以及在函數內部定義的函數
全局名稱空間:即在文件級別定義的名稱空間,在文件級別定義的名字都會放入該空間
內置模塊的名稱空間:builtins
簡單來講:
局部名稱空間:存函數內部定義的名字
全局名稱空間:存文件級別定義的名字
內置名稱空間:存內置的名字
Python中名稱空間的加載順序以及名字的查找順序:
加載順序:
內置模塊的名稱空間====>全局名稱空間====>局部名稱空間
名字的查找順序:
局部名稱空間=====>全局名稱空間====>內置模塊的名稱空間
Python中名稱空間與做用域 的關係:
做用域:全局做用域和局部做用域
其中全局做用域包括內置名稱空間與全局名稱空間定義的名字;局部做用域包括在局部名稱空間定義的名字。
注意:默認狀況下在局部做用域內不能修改全局做用域範圍內的變量,只能調用數值,若是想修改,只能經過global關鍵字進行修改。
示例程序1:
def outer(): a = 0 b = 1 def inner(): print(a) print(b) inner() return 20 outer()
示例程序2:
def outer(): a = 0 b = 1 def inner(): print(a) print(b) b = 4 inner() outer()
錯誤信息:變量b在賦值前被引用。
0 Traceback (most recent call last): File "D:/Python Work Location/Core2/Test3.py", line 16, in <module> outer() File "D:/Python Work Location/Core2/Test3.py", line 14, in outer inner() File "D:/Python Work Location/Core2/Test3.py", line 10, in inner print(b) UnboundLocalError: local variable 'b' referenced before assignment
請繼續關注我