1,函數的命令空間(內置命名空間,全局命名空間,局部命名空間),內置大于全局大于局部
2,內置命名空間,就是Python解釋器一啟動就可以使用的名字,存儲在內置命名空間中,內置的名字(print,input,list,tuple等等),啟動解釋器的時候加載到內存里面;
3,全局命令空間,是在程序從上到下被執行的過程中一次加載到內存的,放置了我們所有的變量名和函數名;
4,局部命名空間,就是函數內部定義的名字,當調用函數的時候,才會產生這個名稱空間,隨著函數執行的結束,這個名稱空間就又消失了
5,在局部,可以使用全局,內置空間中的名字;在全局,可以使用內置空間中的名字,但是不能用局部中中的名字;在內置空間,不能使用局部或者全局的名字
6,在正產改的情況下,直接使用內置的名字,當我在全局中定義了和內置名字空間中同名的名字時,我們會使用全局的名字
7,當我自己有的時候,我就不找上一級要了,當我自己沒有的時候,就找上一級要,上一級也沒有,再找上一級,都沒有,就報錯
8,函數名的本質是函數的內存地址,函數名加上括號,是函數的調用,函數的內存地址加上括號也是函數的調用,估計沒人會這么用
9,作用域有兩種:全局作用域(內置和全局命名空間中的名字術語全局作用域),局部作用域,作用在局部(函數,局部名字空間中的名字術語局部作用域)
10,對于不可變數據類型,在局部可以直接查看全局作用域中的變量,但是不能修改,如果想要修改,需要在程序一開始的時候添加global聲明。
11,如果一個局部函數內聲明了一個global的變量,那么這個變量在局部的所有操作,都是對全局變量的操作
12,locals和globals 查看全局和局部變量,加上global就不在是局部變量了,globals()永遠打印全局變量,locals根據所在位置輸出
a = 1 def func():c =1a = 2# global a# a = 2print(locals())func()運行結果: {'c': 1, 'a': 2}a = 1 def func():c =1# a = 2global aa = 2print(locals())func() 運行結果: {'c': 1}
13,上一小節復習,所有的函數只定義不調用就一定不執行,先定義后調用,直接寫函數名() 這樣不接收返回值,返回值=函數名() 接收返回值 ,只寫一個return是巍峨結束一個函數,返回一個值,結束了函數,且返回一個值
14,復習,形參來說,位置參數必須傳,*args 可以接收零到多個按位置傳入的參數,默認參數,可以不傳,**kwargs:動態參數,可以接收任意多個按照關鍵字傳遞的參數。
15,復習,實參來說,調用的時候,按照位置傳參數,按照關鍵字傳參數,可以混用,但是位置必須在關鍵字之前,不能對一個參數重復賦值。
16,默認參數的陷阱問題,如果默認參數是一個可變的數據類型,那么每一次調用函數,的時候,如果不傳值,就公用這個數據類型的資源
def func(li = []):li.append(1)print(li)func() func() func() func() func([]) # 這兒因為傳入了新的參數列表,不共用,所有其他的使用默認參數的,都共用那一個列表 func()運行結果: [1] [1, 1] [1, 1, 1] [1, 1, 1, 1] [1] [1, 1, 1, 1, 1]
17,對于字典也是一樣的,因為key 不能重復,所以每次值是可以更新的,同樣有陷阱
def func(k,dict1={}):dict1[k]='v'print(dict1.items())func(1) func(3) func(4) func(5) func(6,{}) func(7)運行結果: dict_items([(1, 'v')]) dict_items([(1, 'v'), (3, 'v')]) dict_items([(1, 'v'), (3, 'v'), (4, 'v')]) dict_items([(1, 'v'), (3, 'v'), (4, 'v'), (5, 'v')]) dict_items([(6, 'v')]) dict_items([(1, 'v'), (3, 'v'), (4, 'v'), (5, 'v'), (7, 'v')])
18,三元運算符
# 定義函數找出兩個數中的最大值 def max_of_two(a,b):return a if a>b else b#定義函數,找出三個數中的最大值 def max_of_three(a,b,c):z = max_of_two(a,b) # 函數的嵌套調用return max_of_two(z,c)print(max_of_three(3,4,5))
19,函數的嵌套定義
def outer():def inner():print("i am inner")outer() # 這樣寫并不會打印里面的那句話,因為只是定義了然,然后沒有調用,就結束了
def outer():def inner():print("i am inner")inner() # 加上這句話才會打印的 outer() # 這樣寫并不會打印里面的那句話,因為只是定義了然,然后沒有調用,就結束了
20,內部函數雖然不能直接修改外部函數的變量,但是可以看和使用
def outer():a = 1def inner1():b = 2print(a)print("i am inner")def inner2():print(a,b)print("i am inner2")inner2()inner1() # 加上這句話才會打印的 outer()運行結果: 1 i am inner 1 2 i am inner2
21,本空間有的變量,不會向上一層去找了就,申明了global的變量,只會對全局里面的變量進行操作
a =1 def outer():a = 10def inner1():a = 100 # 本空間有的變量,不會向上去找了就print(a)print("i am inner")def inner2():global a # 不可變數據類型的修改,這樣定義只是修改全局變量的a 并不會修改函數內的aa +=1 # 不可以這樣修改print(a)print("i am inner2")inner2()inner1() # 加上這句話才會打印的 outer()運行結果: 100 i am inner 2 i am inner2
22,不可變數據類型的修改,如果想要修改上層函數內部的變量,而不是全局變量,可以用nonlocal,會一層層往上找,但是不會用全局空間里面的變量
nonlocal只應用于局部變量,找上層中離當前函數最近的一層的局部變量,聲明了nonlocal的內部函數的變量修改會影響到離當前函數最近一層的局部變量
對全局無效,對局部也只是對最近的有這個變量的一層有效。
a =1 def outer():a = 10def inner1():a = 100 # 本空間有的變量,不會向上去找了就print(a)print("i am inner1")def inner2():nonlocal aa +=1 print(a)print("i am inner2")inner2()inner1() # 加上這句話才會打印的 outer()運行結果: 100 i am inner1 101 i am inner2
a =1 def outer():a = 10def inner1():# a = 100 # 本空間有的變量,不會向上去找了就print(a)print("i am inner1")def inner2():nonlocal aa +=1print(a)print("i am inner2")inner2()inner1() # 加上這句話才會打印的 outer()運行結果: 10 i am inner1 11 i am inner2
a =1 def outer():# a = 10 #注釋掉def inner1():# a = 100 # 注釋掉print(a)print("i am inner1")def inner2():nonlocal aa +=1print(a)print("i am inner2")inner2()inner1() # 加上這句話才會打印的 outer()運行結果:File "/Users/guolixiao/PycharmProjects/lisa's_practise/boys/10.2.py", line 28nonlocal a^ SyntaxError: no binding for nonlocal 'a' found
23,后端語言有好多種,Python/java/C/C++/JAVA/PHP,每個語言占得分量差不多,前端語言有HTML/CSS/JS, 其中JS占據著舉足輕重的地位。
24,函數名就是變量地址,函數名可以賦值,函數名可以作為容器類的元素
def func():print("happy day")func2 = func # 注意不加括號才表示地址,加了括號表示調用 li = [func2,func] for i in li:print(i)i()# 其實就理解為普通變量用 運行結果: <function func at 0x10638e840> happy day <function func at 0x10638e840> happy day
25,函數名可以作為函數的參數
def func():print("happy day")def wahaha(f):f()wahaha(func) 運行結果: happy day
26,函數名可以作為返回值
def func():print("happy day")def wahaha(f):f()return f #函數名可以作為返回值 qqxing=wahaha(func) qqxing()運行結果: happy day
27,函數名可以在運行是創建,可以當函數參數或者返回值,可以做容易類型的元素,可存入變量的實體
28,閉包:嵌套函數,內層函數使用外層函數的變量,不適用的話,就不是閉包
def outer():a = 1def inner():print(a)# 這就是一個閉包
29,雙下函數決定是否是閉包 __clousure__
def outer():a = 1def inner():print(a)print(inner.__closure__) outer()運行結果: (<cell at 0x10c269e88: int object at 0x10c01ec00>,)def outer():a = 1def inner():print(1) #不再調用a print(inner.__closure__) outer()運行結果: None
def outer():a = 1def inner():print(a)print(inner.__closure__) outer() print(outer.__closure__)運行結果: (<cell at 0x10edb6e88: int object at 0x10eb6ac00>,) None
30,如何在外部使用內部的函數?return
def outer():a = 1def inner():print("inner")print(a)return innerinn = outer() inn()運行結果: inner 1
31,寫一個閉包的簡單例子
from urllib.request import urlopendef get_url():url = "http://www.xiaohuar.com/"def get():ret=urlopen(url).read()print(ret)return getget_func = get_url() get_func() get_func()# 實現了一個簡單的閉包
?