一、函數對象
什麼是函數?
函數是第一類對象,指的是函數名指向的值(函數)可以被當做資料去使用
1.函數的特性
1.函數可以被引用,即函數可以把值指派給一個變量
def foo():
print('from foo')
foo()
func=foo #引用,指派
func()
print(foo)
print(func)
2.函數可以當做參數傳給另一個函數
def hi():
return "hi yasoob!"
def doSomethingBeforeHi(func):
print("I am doing some boring work before executing hi()")
print(func())
doSomethingBeforeHi(hi)
3.可以當做一個函數的傳回值
def func(): # func=函數的内位址
print('from func')
# print(func)
age=10
def bar(x):
return x
res=bar(age)
print(res)
res=bar(func)
print(res)
4.可以當做容器類型的元素
容器對象(list、dict、set等)中可以存放任何對象,包括整數、字元串,函數也可以作存放到容器對象中
def func(): # func=函數的内位址
print('from func')
age=10
l=[age,func,func()]
print(l)
二、函數嵌套
函數的嵌套又分為兩大類
1.函數的嵌套調用:在調用一個函數的過程中,其内部代碼又調用了其他函數
def max2(x,y):
if x > y:
return x
else:
return y
def max4(a,b,c,d):
res1=max2(a,b)
res2=max2(res1,c)
res3=max2(res2,d)
return res3
print(max4(1,2,3,4))
2.函數的嵌套定義:一個函數内部又定義了另外一個函數
# from math import pi
# # print(pi)
#
# def circle(radius,action=0):
# """
# 圓形相關運算
# :param radius: 半徑
# :param action: 0代表求面積,1代表求周長
# :return: 面積或者周長
# """
# def area(radius):
# return pi * (radius ** 2)
#
# def perimiter(radius):
# return 2 * pi * radius
#
# if action == 0:
# res=area(radius)
# elif action == 1:
# res=perimiter(radius)
#
# return res
#
# print(circle(10,0))
# print(circle(10,1))
三、名稱空間與作用域
1.什麼是名稱空間:
名稱空間就是用來存放名字與記憶體位址綁定關系的地方(記憶體空間),但凡要查找值一定要通過名字,通路名字必須去查找名稱空間
2.名稱空間的三大類
内置名稱空間:存放的是python解釋器自帶的名字 例如:len()、man()等
全局名稱空間:存放的是檔案級别的名字(不是函數内,不是内置的)
x、y、z、b、foo都是全局
m不是
x=1
y=2
if x=1:
z=3
while Ture:
b=4
def foo():
m=3
局部名稱空間:在函數内部定義的
生命周期:
内置名稱空間:在解釋器啟動時生效,關閉時則失效
全局名稱空間:在解釋器解釋執行python檔案時生效,檔案執行完畢後則失效
局部名稱空間:隻在調用函數時臨時産生該函數的局部名稱空間
加載順序:内置===》全局===》局部
查找名字的順序:
基于目前所在位置往上查找,假設目前站在局部,查找順序:局部==》全局==》内置
假設目前站在全局,查找順序:全局=》内置
注:名字的查找順序,在函數定義階段就已經被固定死了(即在檢測文法時就已經确定了名字的查找順序),與函數調 用位置無關,無論在任何地方調用函數,都必須回到當初定義函數的位置去确定名字的查找關系
# x=111
# def outer():
# def inner():
# print('from inner',x) # x通路的時全局名稱空間中x
# return inner
#
# f=outer()
# # print(f)
#
# x=222
# f()
3.作用域
作用域指的是作用的範圍,分為兩種,全局作用域和局部作用域
1.全局作用域:包含的是内置名稱空間與全局名稱空間中的名字
特點:全局有效,全局存活
2.局部作用域:包含的是局部名稱空間中的名字
特點:局部有效,臨時存活
補:global 和 nonlocal
#global:在局部聲明一個名字是來自于全局作用域的,可以用來在局部修改全局的不可變類型
# x=1
# def foo():
# global x
# x=2
#
# foo()
# print(x)
#nonlocal:聲明一個名字是來自于目前層外一層作用域的,可以用來在局部修改外層函數的不可變類型
# x=0
# def f1():
# x=111
# def f2():
# nonlocal x
# x=222
# f2()
# print(x)
#
# f1()
# print(x)
四、閉包函數
1.什麼是閉包函數?
指的是定義一個函數内部的函數,該内部函數包含對外層函數作用域名字的引用
需要結合函數對象的概念将閉包函數傳回到全局作用域去使用,進而打破函數的層級限制。
def outter():
x=111
def inner():
print(x)
return inner
f=outter() #f=outter内的inner
# x=22222
# f()
def func():
x=3333
f()
func()
2.為何要用閉包函數?
閉包函數提供了一種為函數體傳值的解決方案
3.如何使用閉包函數
為函數傳值的方式有兩種,參數和閉包(目前所學)
# 為函數體傳值的方式一:參數
# def func(x,y):
# print(x+y)
#
# func(1,2)
# 為函數體傳值的方式二:閉包
# def outter(x,y):
# # x=1
# # y=2
# def func():
# print(x+y)
# return func
#
# f=outter(1,2)
# f()
閉包的概念有的晦澀難以了解,期待接下裡的學習!
焚膏油以繼晷,恒兀兀以窮年。