第十課:函數做用域 // python 中的嵌套函數 在一個函數中再定義一個函數 # 小結 : # 函數做用域:由於:python是動態語言,定義變量的時候是不須要指定變量類型的,這樣的話,咱們在使用或者定義變量的時候做用域會分不清 # 若是在函數中定義一個變量,並且變量名和該函數上一級的做用域中的變量名相同 # 那麼在該函數使用該變量時,就會使用局部變量 # 若是在函數中使用一個變量,但該變量在函數中並無定義,那麼會到該函數上一層的做用域去尋找該變量,若是尚未找到,會繼續到上一層做用域去尋找,若是沒找到會拋出變量未定義異常 x = 10 # 定義了一個變量 並賦值 def fun1(): x = 100 fun1() print(x) # 10 y = 123 def fun2(): print(y) fun2() # 123 在函數中,若是在函數體中沒有定義變量的話,首先會在函數體中去找 變量的值,若是沒有,就找全局的做用域去找 n = 332 def fun3(): n = 4 print(n) fun3() # 4 這個和第一個例子有什麼區別呢? 多了一個 print(n) 其實這個就是局部做用域,在調用函數的時候就已經算出值了。 def fun4(): print(n) n = 100 # fun4() 拋出異常 # 定義一個嵌套函數 m = 10 def fun5(): # m = 100 def fun6(): print(m) print('fun6') return fun6 # 反映 函數的引用 fun5()() # 100 fun6 調用函數fun6的引用 好比在fun6這個函數中沒有定義m 那麼就會在上一層 m = 100 找 找到了100 那麼就輸出100 接下來 若是註釋掉m = 100 那麼就須要去上一層再找 找了 m = 10 那麼就輸出10 若是再註釋了,那麼就找不到了 就會報錯 ---------------------------------------------------------- 第11課:函數的遞歸 # 函數遞歸:在一個函數中調用函數自己 本身調用本身 # 階乘 # n! = 1 * 2 * 3 * ... *n # n! = (n - 1)! * n n == 0 or n == 1 def jc(n): # 終止條件 if n == 0 or n == 1: return 1 # 返回結果爲1 else: return jc(n - 1) * n print(jc(10)) # 3628800 # 斐波那契數列 : 當前的數列值,表示前2項數列之和 # 0 1 1 2 3 5 8 13 21 # f(n) = f(n - 1) + f(n - 2) # n == 0 return 0 n == 1 return 1 def fibnonacci(n): # 終止條件 if n == 0: return 0 # 直接返回0 elif n == 1: return 1 # 直接返回1 else: return fibnonacci(n - 1) + fibnonacci(n - 2) print(fibnonacci(8)) # 21 -------------------------------------------------------------------------- 第十四課: python變量做用域 局部變量: 好比在函數體內 有用 全局變量: 在整個範圍內都有用 在py中有3個函數 能夠獲取局部變量和全局變量 globals: 獲取全局範圍內全部的變量 locals: 獲取當前做用域內的全部變量 vars(object): 獲取指定對象範圍內全部的變量,若是不指定object ,vars和locals的做用是徹底同樣的 def hanshu(): name = 'majihui' age = 30 print(name,age) # majihui 30 print(locals()) # {'name': 'majihui', 'age': 30} 轉化爲了字典 #print(globals()) #{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7fb62815d7b8>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/Users/majihui/pycharm_work/test07.py', '__cached__': None, 'hanshu': <function hanshu at 0x7fb6280dc268>} # 全局變量輸出的什麼鬼,太多了 print(vars()) # {'name': 'majihui', 'age': 30} #print(vars(object)) # {'__repr__': <slot wrapper '__repr__' of 'object' objects>, '__hash__': <slot wrapper '__hash__' of 'object' objects>, '__str__': <slot wrapper '__str__' of 'object' objects>, '__getattribute__': <slot wrapper '__getattribute__' of 'object' objects>, '__setattr__': <slot wrapper '__setattr__' of 'object' objects>, '__delattr__': <slot wrapper '__delattr__' of 'object' objects>, '__lt__': <slot wrapper '__lt__' of 'object' objects>, '__le__': <slot wrapper '__le__' of 'object' objects>, '__eq__': <slot wrapper '__eq__' of 'object' objects>, '__ne__': <slot wrapper '__ne__' of 'object' objects>, '__gt__': <slot wrapper '__gt__' of 'object' objects>, '__ge__': <slot wrapper '__ge__' of 'object' objects>, '__init__': <slot wrapper '__init__' of 'object' objects>, '__new__': <built-in method __new__ of type object at 0x1034b15e8>, '__reduce_ex__': <method '__reduce_ex__' of 'object' objects>, '__reduce__': <method '__reduce__' of 'object' objects>, '__subclasshook__': <method '__subclasshook__' of 'object' objects>, '__init_subclass__': <method '__init_subclass__' of 'object' objects>, '__format__': <method '__format__' of 'object' objects>, '__sizeof__': <method '__sizeof__' of 'object' objects>, '__dir__': <method '__dir__' of 'object' objects>, '__class__': <attribute '__class__' of 'object' objects>, '__doc__': 'The most base type'} # 輸出的什麼鬼 print(locals()['age']) # 30 locals()['age'] = 50 # 嘗試去修改,結果爲 不會去修改參數值 並非變量自己 print(age) # 30 hanshu() x = 20 y = 40 print(globals()['x']) # 20 #咱們接下來,能夠定義一個對象 class myclass(): def __init__(self): self.name = 'majihui' print(vars(myclass())) # {'name': 'majihui'} #如何在一個函數中使用全局變量 value = 100 def a(): value = 200 # 定義了一個新的局部變量 print(value) a() # 200 ------------------------------------------------------------------------- 第十五課:局部函數 局部變量只在函數的內部起做用, 局部函數和局部的變量是同樣的,只有在函數的內部才能被定義,才能被調用 def process(type,n): def pinfang(n): return n * n def lifang(n): return n * n * n def add(n): return n + n if type == 'pinfan': return pinfang(n) elif type == 'lifang': return lifang(n) else: return add(n) print(process('pinfang',10)) print(process('lifang',10)) print(process('add',10)) 結果爲: 20 1000 20 def xyz(): name = 'majihui' def x(): #print(name) name = 'mjh' print(name) x() xyz() # mjh def xyz(): name = 'majihui' def x(): nonlocal name print(name) name = 'mjh' #print(name) x() xyz() # majihui ---------------------------------------------------------------------- 第十六課 使用函數變量 在python語言中,能夠將函數當成一個變量使用,能夠將一個函數傅給變量 # 這一步將一個函數付給另一個變量的方式 def pow(base,exponent): result = 1 for i in range(1,exponent +1): result *= base return result print(pow(2,10)) # 1024 f = pow print(f(3,10)) # 59049 # 將函數自己最爲一個參數 def area(width,height): return width * height f = area print(f(3,4)) # 12 # 這個area函數也能夠做爲一個函數的參數 def process(fun,a1,a2): return fun(a1,a2) print(process(pow,4,5)) # 1024 print(process(area,10,20)) # 200 # 將函數自己做爲一個返回值 print("-----------") def process1(type): def square(n): return n * n def add(n,m): return n + m if type == 'square': return square else: return add print(process1('square')(12)) # 144 print(process1('add')(12,43)) # 55 --------------------------------------------------------------------- 第十七課 使用lambda表達式代替局部函數 # 使用lambda表達式代替局部函數 # lambda表達式自己就是一個表達式,這個表達式他可傳入一個參數,能夠有1行的執行代碼 # 他實際上就是一個簡化的函數 def get_math_func(type): if type == 'sequare': return lambda n:n * n elif type == 'cube': return lambda n:n * n * n else: return lambda n:n + n math_func01 = get_math_func('sequare') print(math_func01(10)) # 100 math_func02 = get_math_func('cube') print(math_func02(10)) # 1000 math_func03 = get_math_func('add') print(math_func03(10)) # 20 # 調用的方式和其餘的都是同樣的