Python3.5基础——函数的定义与使用

Python3.5基础——函数的定义与使用

1、函数学习框架

2、函数的定义与格式

(1)定义

(2)函数调用

注:函数名称不能以数字开头,建议函数名称的开头用小写的字母

(3)函数有四种格式,分别是:无参数无返回值,有参数无返回值、无参数有返回值、有参数有返回值

#!/usr/bin/env python

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

# Author:ZhengzhengLiu

# 无参数无返回值

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

3、函数的参数

注:定义再函数体内的参数是形参,调用时传入的参数是实参。

函数参数包括:位置参数、关键字参数和不定个数参数

(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 你好

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

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

5、函数的返回值

示例代码:

#多个返回值

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

6、变量的作用域:全局变量与局部变量

在函数的内部,不能识别全局变量,想要在函数内部使用全局变量,需要关键字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

7、匿名函数

示例代码:

#匿名函数——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'}]

8、递归函数

代码示例:

#函数的嵌套

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

利用递归实现阶乘的原理过程:

9、常用内置函数

示例代码:

#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

10、高阶函数

示例代码:

#常用高阶函数

#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

11、约瑟夫环

(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]

12、函数重载

在Python中,没有函数重载,若非要使用函数重载,则后边的同名函数会覆盖掉前面的函数。

#函数重载

def test(x):

    print(x)

def test(x,y):

    print(x+y)

#test(1)  #出错

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

#运行结果:

3

13、函数的嵌套和闭包

(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

14、装饰器

(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...

15、迭代器

#!/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')

猜你喜欢

转载自www.cnblogs.com/waterstar/p/11320889.html