Python3.5基礎——函數的定義與使用

Python3.5基礎——函數的定義與使用python

一、函數學習框架閉包

二、函數的定義與格式app

(1)定義框架

(2)函數調用函數

注:函數名稱不能以數字開頭,建議函數名稱的開頭用小寫的字母學習

(3)函數有四種格式,分別是:無參數無返回值,有參數無返回值、無參數有返回值、有參數有返回值3d

#!/usr/bin/env python日誌

# -*- coding:utf-8 -*-對象

# Author:ZhengzhengLiublog

# 無參數無返回值

defhello():

# 函數體/方法體

print("hello world")

hello()

# 有參數無返回值

defadd(x, y):

    print(x + y)

add(10,20)

# 無參數有返回值

defsleep():

return"sleep"

s = sleep()

print(s)

# print(sleep())      等價於上面兩句

# 有參數有返回值

defsub(x, y):

returnx * y

res = sub(12,6)

print(res)

#運行結果

hello world

30

sleep

72

三、函數的參數

注:定義再函數體內的參數是形參,調用時傳入的參數是實參。

函數參數包括:位置參數、關鍵字參數和不定個數參數

(1)位置參數、關鍵字參數

示例代碼:

#位置參數

deftest(x,y,z):

    print(x,y,z)

test(1,2,3)

#關鍵字參數

deftest1(x,y,z=10):

    print(x,y,z)

test1(1,2,3)

test1(1,2)#關鍵字參數,z採用默認的參數值

test1(x=2,z=3,y=1)#調用時的關鍵字參數

#運行結果:

123

123

1210

213

(2)默認參數

注:帶有默認值參數的形參必須放在參數的最後面的位置。

(3)不定個數參數,用*args   和    **kwarg

總結:

(1)定義時  *的做用  將位置實參裝配成元組

定義時  **的做用  將關鍵字實參裝配成字典

(2)調用時  *做用  將元組或列表打散成位置參數進行參數傳遞

調用時  **做用  將字典打散成關鍵字參數進行參數傳遞

#不定個數參數

deftest2(x,y,z,*args):

    print(x,y,z,args)

#定義時  *的做用  將位置實參裝配成元組

test2(1,2,3,4,6,7,8,9)

deftest3(x,y,z,**kwargs):

    print(x,y,z,kwargs)

#定義時  **的做用  將關鍵字實參裝配成字典

test3(1,2,3,a=6,b=19,c=8)

defts(x,*args,**kwargs):

    print(x,args,kwargs)

ts(1,2,3,a=6,b=19,c=8)

deftest4(x,y,z):

    print(x,y,z)

x = [1,2,3]

y = {"x":1,"y":"hello","z":"你好"}

test4(*x)#調用時  *做用  將元組或列表打散成位置參數進行參數傳遞

test4(**y)#調用時  **做用  將字典打散成關鍵字參數進行參數傳遞

#運行結果:

123(4,6,7,8,9)

123{'b':19,'a':6,'c':8}

1(2,3) {'b':19,'a':6,'c':8}

123

1hello 你好

四、函數的傳值:基本類型傳值調用、非基本類型參數傳遞調用(強引用與弱引用)

#!/usr/bin/env python

# -*- coding:utf-8 -*-

# Author:ZhengzhengLiu

#基本類型傳值調用

deftest(x):

    print(x)

test(10)

#非基本類型參數傳遞調用

li = [1,2,3,4]

print(id(li))#打印傳遞前的地址

deftest1(x):

    print(id(x))

x[0] =2#修改第一個參數爲2

    print(x)

test1(li)#強引用(傳址調用,列表裏面的內容會進行修改)

#test1(list(li))  #弱引用(用list能夠消除強引用,不能修改列表裏的元素)

foriinli:

    print(i)

#運行結果:(強引用傳址調用)

10

17741864

17741864

[2,2,3,4]

2

2

3

4

#!/usr/bin/env python

# -*- coding:utf-8 -*-

# Author:ZhengzhengLiu

#基本類型傳值調用

deftest(x):

    print(x)

test(10)

#非基本類型參數傳遞調用

li = [1,2,3,4]

print(id(li))#打印傳遞前的地址

deftest1(x):

    print(id(x))

x[0] =2#修改第一個參數爲2

    print(x)

#test1(li)    #強引用(傳址調用,列表裏面的內容會進行修改)

test1(list(li))#弱引用(用list能夠消除強引用,傳值調用,不能修改列表裏的元素)

foriinli:

    print(i)

#運行結果:(弱引用,傳值調用)

10

18501544

18613272

[2,2,3,4]

1

2

3

4

#不可變對象——傳遞對象的值,修改值修改的是另外一個複製對象,不影響原來對象自己

defgetNum(a):

a =10

print("函數內變量a的值:",a)

a =8

getNum(a)

print("函數外變量a的值:",a)

#可變對象——傳遞對象自己,函數內部修改值會影響對象自己

list01 = [0,1,2,3]

defgetNum1(num):

num.append(4)

    print(num)

    print(id(num))

getNum1(list01)

print(list01)

print(id(list01))

#運行結果:

函數內變量a的值:10

函數外變量a的值:8

[0,1,2,3,4]

5908280

[0,1,2,3,4]

5908280

五、函數的返回值

示例代碼:

#多個返回值

defre(a,b):

a *=10

b *=10

returna,b

num = re(1,2)

print(type(num))#若是返回多個值,而且存在一個變量中,會以元組的形式保存

print(num)

#分別獲取多個返回值

re1,re2 = re(3,4)

print(type(re1))

print(re1,re2)

#運行結果:

(10,20)

30 40

簡單實例練習:

defoperation(a,b,opt):

ifopt =="+":

returna+b

elifopt =="-":

returna-b

elifopt =="*":

returna*b

elifopt =="/":

returna/b

else:

return"輸入有誤"

num1 = int(input("請輸入第一個字符:"))

num2 = int(input("請輸入第二個字符:"))

op = input("請輸入運算符:")

result = operation(num1,num2,op)

print(result)

#運行結果:

請輸入第一個字符:1

請輸入第二個字符:2

請輸入運算符:+

3

六、變量的做用域:全局變量與局部變量

在函數的內部,不能識別全局變量,想要在函數內部使用全局變量,須要關鍵字global,但不建議這樣使用,使用global具備污染性。

(1)局部變量

(2)全局變量

(3)當全局變量與局部變量同名時,優先使用局部變量

#全局變量與局部變量同名

a =10#全局變量

print("全局變量a:%d"%a)

deftest01():

a =20

print("test01中的a:%d"%a)

deftest02():

print("test02中的a:%d"%a)

test01()

test02()

#運行結果:

全局變量a:10

test01中的a:20

test02中的a:10

(4)修改全局變量

#!/usr/bin/env python

# -*- coding:utf-8 -*-

# Author:ZhengzhengLiu

i =20

deftest():

#i += 10        #函數內部直接修改全局的值(錯誤)

globali#函數內部修改全局的值用global關鍵字

i +=10

print(i)#獲取全局變量的值

test()

#運行結果:

30

注:上邊代碼中,函數內修改不可變類型的全局變量,須要經過global關鍵字

總結:對不可變類型變量從新賦值,其實是從新建立一個不可變類型對象,並將原來的變量指向新建立的對象。

若是沒有其餘變量引用原有對象的話(即:引用計數爲0),原有對象就會被回收。

(5)可變類型的全局變量:函數內修改可變類型的全局變量,能夠不使用global關鍵字

#函數內修改可變類型的全局變量——直接修改,無需使用global關鍵字

a = [100,200,300]

print("可變類型全局變量a:",a)

print("可變類型全局變量a的地址:%d"%id(a))

deftest01():

a.append(400)

print("test01函數內修改可變類型全局變量a:",a)

print("test01函數內修改可變類型全局變量後a的地址:%d"%id(a))

deftest02():

print("test02函數內使用可變類型全局變量a:",a)

print("test02函數內使用可變類型全局變量a的地址:%d"%id(a))

test01()

test02()

#運行結果:

可變類型全局變量a: [100,200,300]

可變類型全局變量a的地址:18241896

test01函數內修改可變類型全局變量a: [100,200,300,400]

test01函數內修改可變類型全局變量後a的地址:18241896

test02函數內使用可變類型全局變量a: [100,200,300,400]

test02函數內使用可變類型全局變量a的地址:18241896

七、匿名函數

示例代碼:

#匿名函數——lambda

#語法:lambda arg1[,arg2...]:表達式    默認return

num =lambdaa,b:a+b

print(num(1,2))

#運行結果:

3

簡單應用(一):

#四則運算——利用lambda表達式

defoperation(a,b,opt):

    re = opt(a,b)

returnre

num1 = int(input("請輸入第一個字符:"))

num2 = int(input("請輸入第二個字符:"))

result = operation(num1,num2,lambdaa,b:a+b)

print(result)

#運行結果:

請輸入第一個字符:2

請輸入第二個字符:3

5

簡單應用(二):

#列表中的字典元素進行排序——lambda表達式

students = [

{"name":"Joe","age":"18"},

{"name":"Tom","age":"20"},

{"name":"Susan","age":"16"}

]

students.sort(key=lambdax:x["name"])#對字典按照關鍵字name排序

print(students)

#運行結果:

[{'age':'18','name':'Joe'}, {'age':'16','name':'Susan'}, {'age':'20','name':'Tom'}]

八、遞歸函數

代碼示例:

#函數的嵌套

deftest1():

print("in test1...")

deftest2():

    test1()

print("in test2...")

deftest3():

    test2()

print("in test3...")

test3()

#運行結果:

intest1...

intest2...

intest3...

#遞歸函數

deffunc(n):

print("進入第%d層夢"%n)

ifn ==3:

print("進入潛意識區")

else:

func(n+1)

print("從第%d層夢中醒來"%n)

func(1)

#運行結果:

進入第1層夢

進入第2層夢

進入第3層夢

進入潛意識區

從第3層夢中醒來

從第2層夢中醒來

從第1層夢中醒來

應用:求階乘

#階乘——利用while

i =1

num =1

whilei <=4:

    num = num*i

i+=1

print(num)

#階乘——利用遞歸

deffunc01(n):

ifn ==1:

return1

returnn*func01(n-1)

print(func01(4))

#運行結果:

24

24

利用遞歸實現階乘的原理過程:

九、經常使用內置函數

示例代碼:

#abs()——絕對值函數

num =-1

print(abs(num))

#sorted()——排序函數

list01 = [1,4,2,7,9,3]

print(sorted(list01))#由小到大排序

print(sorted(list01,reverse=True))#由大到小排序

#sum()——求和

print(sum(list01))

#round()——四捨五入,獲取指定位數的小數

print(round(3.1415926,2))

#pow()——乘方數(冪)

print(pow(2,3))

#isinstance——類型判斷

num1 =5

print(isinstance(num1,int))

#eval()——執行表達式或字符串做爲運算

print(eval("1+3"))

#exec()——執行Python語句

exec('print("Hello")')

#運行結果:

1

[1,2,3,4,7,9]

[9,7,4,3,2,1]

26

3.14

8

True

4

Hello

十、高階函數

示例代碼:

#經常使用高階函數

#map()

num1 = map(lambdax:x*2,[1,2,3,4,5])

print(num1)

foriinnum1:#遍歷map對象的內容

print(i,end=" ")

print()

#filter()

num2 = filter(lambdax:x%2==1,[1,2,3,4,5,6,7,8,9,10])

print(num2)

forjinnum2:#遍歷filter對象的內容

print(j,end=" ")

print()

#reduce()

from functool simport reduce

print(reduce(lambdax,y:x+y,[1,2,3,4],10))#10是起始值

#運行結果:

246810

13579

20

name = ["joe","jack","TOM","suSAN"]

age = [17,18,20,15]

sex = ["M","M","M","F"]

#案例一——格式化英文名。首字母大寫,其餘小寫

names = map(lambda t:t[0:1].upper()+t[1:].lower(),name)

for stu_name in names:

print(stu_name,end=" ")

print()

#案例二——將三個序列結合到一塊兒,造成一個集合

newStu = map(lambda n,a,s:(n,a,s),name,age,sex)

student = []

for tup in  newStu:

    student.append(tup)

print(student)

#案例三——過濾性別爲男的用戶

males = filter(lambda x:x[2] =="M",student)

man = []

for m in males:

    man.append(m)

print(man)

#案例四——求性別爲男的用戶的平均年齡

from functools import reduce

man_count = len(man)

total_age = reduce(lambda x,y:x+y[1],man,0)

print("總年齡:",total_age)

print("平均年齡:%.2f"%(total_age/man_count))

#運行結果:

Joe Jack Tom Susan

[('joe',17,'M'), ('jack',18,'M'), ('TOM',20,'M'), ('suSAN',15,'F')]

[('joe',17,'M'), ('jack',18,'M'), ('TOM',20,'M')]

總年齡:55

平均年齡:18.33

十一、約瑟夫環

(1)一羣人圍在一塊兒坐成環狀(如:N)

(2)從某個編號開始報數(如:K)

(3)數到某數(如:M)的時候,此人出列,下一我的從新報數

(4)一直循環,直到全部人出列,約瑟夫環結束

約瑟夫環實現代碼:

#約瑟夫環問題

# n=9(總人數)  m = 3(報數) k:索引

#k = (k+(m-1))%len(list)

deffunc(n,m):

#生成一個列表

people = list(range(1,n+1))

k =0#定義開始的索引

#開始循環報數

whilelen(people) >2:

k = (k+(m-1))%len(people)

print("kill:",people[k])

del(people[k])

        print(k)

returnpeople

print(func(9,3))

#運行結果:

kill:3

2

kill:6

4

kill:9

6

kill:4

2

kill:8

4

kill:5

2

kill:2

1

[1,7]

十二、函數重載

在Python中,沒有函數重載,若非要使用函數重載,則後邊的同名函數會覆蓋掉前面的函數。

#函數重載

def test(x):

    print(x)

def test(x,y):

    print(x+y)

#test(1)  #出錯

test(1,2)#覆蓋test(x)

#運行結果:

3

1三、函數的嵌套和閉包

(1)函數嵌套:在函數內部再定義新的函數

#!/usr/bin/env python

# -*- coding:utf-8 -*-

# Author:ZhengzhengLiu

#函數嵌套

def test():

def test1():

def test2():

print("hello")

return test2

return test1

res = test()#test函數返回值res是一個函數,等價於res ==> test1

re = res()#res() ==>test1()  ,test1函數返回值re是一個函數,re==>test2

re()#re() ==> test2()

#運行結果:

hello

(2)閉包:內部函數能夠取到外部函數的局部變量

#閉包:內部函數能夠取到外部函數的局部變量

deftest(x):

deftest1(y):

deftest2(z):

            print(x+y+z)

returntest2

returntest1

res = test(10)

re = res(20)

re(30)

#運行結果:

6

1四、裝飾器

(1)形象舉例:照片與相框

照片:被裝飾的對象,相框:裝飾對象。

裝飾做用:動態擴展裝飾,即:不會改變被裝飾的對象(照片)的內容,只是動態改變裝飾的對象(相框)。

(2)裝飾器修飾無參數的函數

#!/usr/bin/env python

# -*- coding:utf-8 -*-

# Author:ZhengzhengLiu

#裝飾器——日誌管理

def log(func):#log(func)==> func = delete(delete函數做爲實參傳入到func)

def warp():

print("logger strating...")

func()#運行delete

print("logger ending...")

return warp

@log  #用log來裝飾delete,等價於delete = log(delete) = warp

defdelete():

print("deleting...")

delete()#執行warp

#運行結果:

logger strating...

deleting...

logger ending...

(3)裝飾器修飾有參數和返回值的函數

#裝飾器修飾有參數、有返回值的函數

deflog(func):#log(func)==> func = delete(delete函數做爲實參傳入到func)

defwarp(*args,**kwargs):

print("logger strating...")

res = func(*args,**kwargs)#運行delete

        print(res)

print("logger ending...")

returnwarp

@log  #用log來裝飾delete,等價於delete = log(delete) = warp

defdelete(name,age):

print("deleting...")

    print(name,age)

return"delete success"

delete("liu",20)#執行warp

#運行結果:

logger strating...

deleting...

liu20

delete success

logger ending...

(4)裝飾器自身帶有參數

#裝飾器帶有參數

deflog(i):

defwarp1(func):

defwarp2(*args,**kwargs):

print("logger strating...")

ifi>0:

print("logging success...")

                func(*args, **kwargs)

else:

print("logging failed...")

print("logger ending...")

returnwarp2

returnwarp1

@log(1)

defdelete():

print("deleting...")

delete()

#運行結果:

logger strating...

logging success...

deleting...

logger ending...

#裝飾器帶有參數

deflog(i):

defwarp1(func):

defwarp2(*args,**kwargs):

print("logger strating...")

ifi>0:

print("logging success...")

                func(*args, **kwargs)

else:

print("logging failed...")

print("logger ending...")

returnwarp2

returnwarp1

@log(-1)

defdelete():

print("deleting...")

delete()

#logger strating...

logging failed...

logger ending...

1五、迭代器

#!/usr/bin/env python

# -*- coding:utf-8 -*-

# Author:ZhengzhengLiu

#迭代器——笛卡爾積

impor titer tools

x = range(1,6)

coml = itertools.combinations(x,3)#排列

coml2 = itertools.permutations(x,4)#組合

y = ["a","b","c"]

coml3 = itertools.product(x,y)#笛卡爾積

coml4 = itertools.chain(coml,coml2,coml3)

forhincoml4:

    print(h)

運行結果:

(1,2,3)

(1,2,4)

(1,3,4)

(2,3,4)

(1,2,3,4)

(1,2,4,3)

(1,3,2,4)

(1,3,4,2)

(1,4,2,3)

(1,4,3,2)

(2,1,3,4)

(2,1,4,3)

(2,3,1,4)

(2,3,4,1)

(2,4,1,3)

(2,4,3,1)

(3,1,2,4)

(3,1,4,2)

(3,2,1,4)

(3,2,4,1)

(3,4,1,2)

(3,4,2,1)

(4,1,2,3)

(4,1,3,2)

(4,2,1,3)

(4,2,3,1)

(4,3,1,2)

(4,3,2,1)

(1,'a')

(1,'b')

(1,'c')

(2,'a')

(2,'b')

(2,'c')

(3,'a')

(3,'b')

(3,'c')

(4,'a')

(4,'b')

(4,'c')

相關文章
相關標籤/搜索