您好,登錄后才能下訂單哦!
函數是python為了代碼最大程度的重用和最小化代碼冗余而提供的最基本的程序結構。函數也是一種設計工具,使用函數,我們也可以把復雜的系統分解為可管理的部件
函數的相關語句和表達式
語句 | 例子 |
---|---|
Calls | my_function('Fir Arg','Sec Arg') |
def | def myfunction(fir_arg,sec_arg): |
return | return fir_arg+sec_arg |
global | global x;x=new_value |
nonlocal | nonlocal x;x=new_value |
yield | def my_sqr(x): for i in range(x): yield i **2 |
lambda | funcs=[lambda x: x*2,lambda x:x3] |
def是可執行的代碼。在python里,只有def執行之后,才會生成相應的函數。要是def沒有執行,相應的函數就不會生成。def語句在if、while語句甚至是其他def語句里也是合法的。
def語句將創建一個函數并將其賦值給一個變量名:
def <變量名>([參數1,參數2,...]):
<語句>
def語句的首行定義函數名,并引用函數對象,函數名的本質就是函數的內存地址。
參數個數是0或以上數目。
語句里,可以包含return語句,在調用函數時,會返回一個值。當沒有return時,默認返回值為None。
函數里,也可以使用yield語句來生成返回值。
因為def是執行語句,因此函數是實時生成的
>>> def hanshu(x,y):
return x*y
>>> hanshu('abc',2)
'abcabc'
>>> hanshu(2,[1,2,3])
[1, 2, 3, 1, 2, 3]
在這個函數里,x*y的結果取決于x和y的對象類型,因為python本身不定義變量,因此傳遞的值的類型與返回的類型都不一定是固定的類型。
作用域針對的是變量。在使用同一個變量名時,會出現作用域問題。
>>> x=10 #全局變量
>>> def funx():
x=20 #本地變量
print(x)
>>> print(x) #打印的是全局變量
10
>>> funx() #打印的是本地變量
20
>>> x=10
>>> def funx():
print(x)
#本地變量沒有定義的話會引用全局的變量
>>> print(x)
10
>>> funx()
10
變量名使用時,查找順序:
>>> def newdef():
x=20
def newdef2():
print(x)
newdef2()
>>> newdef()
20
>>> x=10
>>> def newdef():
def newdef2():
print(x)
newdef2()
>>> newdef()
10
在函數內,想改變全局變量,可以使用global語句來定義此變量為全局變量。
>>> g='global'
>>> l='global'
>>> def glo():
global g
g='local'
l='local'
>>> g
'global'
>>> l
'global'
>>> glo()
>>> g
'local'
>>> l
'global'
在glo函數里,都重新賦值了g與l,但在函數執行后只有g改變了,當使用global之后,當前函數里所使用的所有對變量g的更改都會對全局變量g進行更改。
除了這個方法,還有引用自己的方法(交互模式里,可以import main)與sys.modules的方法(可以使用引用過的所有模塊,交互模式里本身可用main方式)。
>>> x=10
>>> import __main__
>>> __main__.x
10
>>> def glo():
__main__.x+=1
>>> glo()
>>> x
11
>>> s=10
>>> import sys
>>> sys.modules['__main__'].s
10
>>> def glo():
sys.modules['__main__'].s+=1
>>> glo()
>>> s
11
被嵌套函數的作用域就是上級函數,在這里,想調用inner函數,必須是在函數outer里面,不能直接使用。可以使用返回內部函數的方法來提取內部函數:
>>> def outer():
def inner():
print('inner')
inner()
>>> func1=outer()
inner
工廠函數:根據要求的對象,一個能夠記住嵌套作用域的變量值的函數。
>>> def printx(x):
def printy(y): #嵌套函數
return x*y #返回x*y的值
return printy #返回嵌套的函數
>>> a=printx(3) #定義x值為3后的嵌套函數賦值
>>> a(2)
6
>>> a(3)
9
nonlocal讓內部函數中的變量在上一層及以下層函數中生效(父級級父級以下)
x=1
>>> def func1():
x=2
def func2():
nonlocal x
x=3
return x
func2()
print(x)
>>> func1()
3
>>> x
1
因為x并不是全局變量,所以只有在調用函數時nonlocal語句才會生效,這里x=3,當直接輸出x而不調用函數時那么x=1
參數:argement或parameter,對象作為輸入值傳遞給函數的方式。
參數傳遞時的簡要關鍵點:
傳遞參數為可變對象與不可變對象時:
不可變對象通過值進行傳遞——數值、字符串等
可變對象是通過指針進行傳遞——列表、字典等
>>> a=3
>>> def printa(a):
a=a+1
print(a)
>>> a
3
>>> printa(a)
4
>>> a
3
在這里,b[:]方式會新生成一個列表對象,因此函數里的y與setlist(b[:])是兩個不同的對象。這種方法可以避免可變參數的修改。
>>> def setlist(y):
y.append(3)
>>> a=[1,2]
>>> setlist(a[:])
>>> a
[1, 2]
>>> setlist(a)
>>> a
[1, 2, 3]
參數傳遞是由特定匹配規則的:
傳遞參數時,要注意順序:非關鍵字參數->關鍵字參數->字典參數
>>> def myfunc(a,b):
print(a,b)
>>> myfunc(1,2)
1 2
>>> myfunc(b=1,a=2)
2 1
語法 | 位置 |
---|---|
func(value) | 調用者 常規參數:通過位置進行匹配 |
func(name=value) | 調用者 關鍵字參數:通過變量名匹配 |
func(*sequence) | 調用者 迭代傳遞所有元素 |
func(**dict) | 調用者 以‘鍵’為關鍵字,‘值’為相應值的方式傳遞字典所有元素 |
def func(name) | 函數 常規參數:通過位置或變量名進行匹配 |
def func(name=value) | 函數 默認參數值:如果沒有在調用中傳遞的話 |
def func(*name) | 函數 匹配并收集(在元組中)所有包含位置的參數 |
def func(**name) | 函數 匹配并收集(在字典中)所有包含關鍵字的參數 |
def func(*arg,name) | 函數 參數必須在調用中按照關鍵字傳遞 |
常規參數函數用法:
>>> def myfunc(a,b):
result=a+b
print(result)
>>> myfunc(1,2)
3
關鍵字參數函數:
>>> def myfunc(a,b):
result=a+b
print(result)
>>> myfunc(b=1,a=3)
4
迭代傳遞參數用法:
>>> def myfunc(a,b,c):
result=a+b+c
print(result)
>>> myfunc(*[1,2,3])
6
在字典中匹配所有參數用法:
>>> def myfunc(a,b,c):
result=a+b+c
print(result)
>>> myfunc(**{'a':1,'b':2,'c':3})
6
>>> myfunc(1,**{'b':2,'c':3})
6
默認參數函數用法:
>>> def myfunc(a,b=3):
print(a+b)
#當有默認參數存在時,可以只傳入其他的參數
>>> myfunc(3)
6
>>> myfunc(3,2)
5
可變參數函數用法:
可變參數,可以傳遞任意個參數
*args方式是把所有常規參數調用與迭代調用放進一個元組里:
>>> def myfunc(*a):
result=''.join(a)
print (result)
>>> myfunc('1,','2,','3')
1,2,3
>>> myfunc('first,',*['second,','third'])
first,second,third
**args方法是把任意個關鍵字參數與字典調用方式存放在變量名為args的字典里
>>> def myfunc(**a):
print(a)
>>> myfunc(a='1',b='2')
{'a': '1', 'b': '2'}
>>> myfunc(a='1',b='2',**{'c':'3'})
{'a': '1', 'b': '2', 'c': '3'}
必須使用關鍵字傳遞的方法:
函數里的參數:
常規——有/無默認值
*args——存放在列表
*args——存放在字典
在python3開始,在args與args中間可以加入一個“必須使用關鍵字傳遞的參數”
使用方法為是0個或多個常規參數+或args+“必須使用關鍵字傳遞的參數”+0個或1個args。
>>> def myfunc(*,b,**c):
print(b,c)
>>> myfunc(**{'b':4})
4 {}
>>> def myfun(*a,b,**c):
print(a,b,c)
>>> myfun(2,**{'b':4,'c':5})
(2,) 4 {'c': 5}
特殊參數的傳遞:
在python里,函數也是對象,函數名也是變量名,因此函數本身也可以傳遞。
計算最大、最小值的函數時,一般用法:
#這是一個求最小值的函數
>>> def min1(*a):
reg=a[0]
for i in a[1:]:
if i <reg:
reg=i
print(reg)
>>> min1(2,3,5,1,6,8)
1
#這里將最大和最小值的函數作為參數傳入到求最大和最小值的函數里
>>> def lessthan(x,y):
return x<y
>>> def morethan(x,y):
return x>y
>>> def minmax(test,*args):
res=args[0]
for i in args[1:]:
if test(i,res):
res=i
print(res)
>>> minmax(lessthan,2,3,5,1,6)
1
>>> minmax(morethan,2,3,5,1,6)
6
>>> def mysum(s):
if not s:
return 0
else:
return s[0]+mysum(s[1:])
#或
>>> def mysum(s):
return 0 if not s else s[0]+mysum(s[1:])
>>> mysum([1,2,3,4])
10
嵌套列表里面的值相加
>>> li=[1,2,[3,4,5],6,[7,[8,9],10]]
>>> def sumlist(a):
sum=0
for i in a:
if not isinstance(i,list): #判斷遍歷的i是否是列表
sum += i
else:
sum += sumlist(i)
return sum
>>> sumlist(li)
55
在python里函數也是以對象的形態出現。函數名也是以變量名形式存放。因此函數也可以跨模塊,以參數傳遞等形式。函數對象也能調用根本無關的操作:屬性存儲與注釋。
間接函數調用:
>>> def func(x):
print(x)
>>> func2=func
>>> func2(2)
2
把函數放進列表或元組里:
>>> def myfunc(func_name,arg1):
func_name(arg1)
>>> def func_name(arg1):
print (arg1)
>>> li=[(func_name,1),(func_name,2),(func_name,3)]
>>> for i in li:
myfunc(i[0],i[1])
1
2
3
lambda會生成函數對象,但不賦值給任何變量。
lambda表達式:
lambda [<arg1>
][,<arg2>
][,<arg3>
]....:expression using args
參數不是必須的,但沒有參數就沒有相對意義。
lambda簡單說明:
lambda是一個表達式,而不是一個語句,也不是一個的代碼塊。——生成一個對象。
>>> myfunc=lambda a:a*2
>>> myfunc(4)
8
>>> (lambda a,b:a*b)(5,4)
20
當我們把函數對象放進列表里等操作的時候,使用def感覺很臃腫,這時可以使用lambda來簡化過程。
>>> funclist=[lambda x: x**2,
lambda x: x**3,
lambda x: x**4]
>>> funclist[0](2)
4
>>> funclist[1](3)
27
使列表中的每個值都加10
>>> l=[1,2,3,4]
>>> list(map(lambda x: x+10,l))
[11, 12, 13, 14]
filter與map相似,但是針對返回的bool結果判斷,結果為真,保留元素;結果為假,棄用元素。結果也是保存在可迭代對象里:
>>> list(filter(lambda x: x>1,[-1,0,1,2,3,4,5]))
[2, 3, 4, 5]
reduce函數是在functools模塊里的,因此我們需要導入這個函數。
這個方法是第一次從可迭代對象里提取兩個元素當作函數的參數傳入,按前面的函數進行運算,保存返回值,當可迭代對象里還有元素的時候,之前的返回值為第一個參數,可迭代對象里取下一個繼續運算,知道可迭代對象空。最后返回函數的返回值。
>>> from functools import reduce
>>> reduce(lambda x,y: x+y,[1,2,3,4])
10
>>> reduce(lambda x,y:x if x>y else y,[3,5,2,6,7,4,1,9])
9
歡迎各×××陳師傅”
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。