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

来源:互联网 发布:网络架构师 真题 编辑:程序博客网 时间:2024/05/16 08:36

1、函数学习框架


2、函数的定义与格式

(1)定义




(2)函数调用


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

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


#!/usr/bin/env python# -*- coding:utf-8 -*-# Author:ZhengzhengLiu# 无参数无返回值def hello():    # 函数体/方法体    print("hello world")hello()# 有参数无返回值def add(x, y):    print(x + y)add(10, 20)# 无参数有返回值def sleep():    return "sleep"s = sleep()print(s)# print(sleep())       等价于上面两句# 有参数有返回值def sub(x, y):    return x * yres = sub(12, 6)print(res)#运行结果hello world30sleep72

3、函数的参数



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


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

(1)位置参数、关键字参数




示例代码:

#位置参数def test(x,y,z):    print(x,y,z)test(1,2,3)#关键字参数def test1(x,y,z=10):    print(x,y,z)test1(1,2,3)test1(1,2)      #关键字参数,z采用默认的参数值test1(x=2,z=3,y=1)   #调用时的关键字参数#运行结果:1 2 31 2 31 2 102 1 3

(2)默认参数


注:带有默认值参数的形参必须放在参数的最后面的位置。


(3)不定个数参数,用*args   和    **kwarg


总结:

1定义时  *的作用  将位置实参装配成元组

定义时  **的作用  将关键字实参装配成字典

(2)调用时  *作用  将元组或列表打散成位置参数进行参数传递

调用时  **作用  将字典打散成关键字参数进行参数传递

#不定个数参数def test2(x,y,z,*args):    print(x,y,z,args)#定义时  *的作用  将位置实参装配成元组test2(1,2,3,4,6,7,8,9)def test3(x,y,z,**kwargs):    print(x,y,z,kwargs)#定义时  **的作用  将关键字实参装配成字典test3(1,2,3,a=6,b=19,c=8)def ts(x,*args,**kwargs):    print(x,args,kwargs)ts(1,2,3,a=6,b=19,c=8)def test4(x,y,z):    print(x,y,z)x = [1,2,3]y = {"x":1,"y":"hello","z":"你好"}test4(*x)       #调用时  *作用  将元组或列表打散成位置参数进行参数传递test4(**y)      #调用时  **作用  将字典打散成关键字参数进行参数传递#运行结果:1 2 3 (4, 6, 7, 8, 9)1 2 3 {'b': 19, 'a': 6, 'c': 8}1 (2, 3) {'b': 19, 'a': 6, 'c': 8}1 2 31 hello 你好

4、函数的传值:基本类型传值调用、非基本类型参数传递调用(强引用与弱引用)


#!/usr/bin/env python# -*- coding:utf-8 -*-# Author:ZhengzhengLiu#基本类型传值调用def test(x):    print(x)test(10)#非基本类型参数传递调用li = [1,2,3,4]print(id(li))    #打印传递前的地址def test1(x):    print(id(x))    x[0] = 2   #修改第一个参数为2    print(x)test1(li)    #强引用(传址调用,列表里面的内容会进行修改)#test1(list(li))   #弱引用(用list可以消除强引用,不能修改列表里的元素)for i in li:    print(i)#运行结果:(强引用传址调用)101774186417741864[2, 2, 3, 4]2234

#!/usr/bin/env python# -*- coding:utf-8 -*-# Author:ZhengzhengLiu#基本类型传值调用def test(x):    print(x)test(10)#非基本类型参数传递调用li = [1,2,3,4]print(id(li))    #打印传递前的地址def test1(x):    print(id(x))    x[0] = 2   #修改第一个参数为2    print(x)#test1(li)    #强引用(传址调用,列表里面的内容会进行修改)test1(list(li))   #弱引用(用list可以消除强引用,传值调用,不能修改列表里的元素)for i in li:    print(i)#运行结果:(弱引用,传值调用)101850154418613272[2, 2, 3, 4]1234

#不可变对象——传递对象的值,修改值修改的是另一个复制对象,不影响原来对象本身def getNum(a):    a = 10    print("函数内变量a的值:",a)a = 8getNum(a)print("函数外变量a的值:",a)#可变对象——传递对象本身,函数内部修改值会影响对象本身list01 = [0,1,2,3]def getNum1(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、函数的返回值

示例代码:

#多个返回值def re(a,b):    a *= 10    b *= 10    return a,bnum = re(1,2)print(type(num))        #如果返回多个值,并且存在一个变量中,会以元组的形式保存print(num)#分别获取多个返回值re1,re2 = re(3,4)print(type(re1))print(re1,re2)#运行结果:<class 'tuple'>(10, 20)<class 'int'>30 40

简单实例练习:


def operation(a,b,opt):    if opt == "+":        return a+b    elif opt == "-":        return a-b    elif opt =="*":        return a*b    elif opt =="/":        return a/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)def test01():    a = 20    print("test01中的a:%d"%a)def test02():    print("test02中的a:%d"%a)test01()test02()#运行结果:全局变量a:10test01中的a:20test02中的a:10

(4)修改全局变量


#!/usr/bin/env python# -*- coding:utf-8 -*-# Author:ZhengzhengLiui = 20def test():    #i += 10        #函数内部直接修改全局的值(错误)    global i       #函数内部修改全局的值用global关键字    i += 10    print(i)        #获取全局变量的值test()#运行结果:30

注:上边代码中,函数内修改不可变类型的全局变量,需要通过global关键字


总结:对不可变类型变量重新赋值,实际上是重新创建一个不可变类型对象,并将原来的变量指向新创建的对象。

如果没有其他变量引用原有对象的话(即:引用计数为0),原有对象就会被回收。

(5)可变类型的全局变量:函数内修改可变类型的全局变量,可以不使用global关键字


#函数内修改可变类型的全局变量——直接修改,无需使用global关键字a = [100,200,300]print("可变类型全局变量a:",a)print("可变类型全局变量a的地址:%d" %id(a))def test01():    a.append(400)            print("test01函数内修改可变类型全局变量a:",a)    print("test01函数内修改可变类型全局变量后a的地址:%d" %id(a))def test02():    print("test02函数内使用可变类型全局变量a:",a)    print("test02函数内使用可变类型全局变量a的地址:%d" %id(a))test01()test02()#运行结果:可变类型全局变量a: [100, 200, 300]可变类型全局变量a的地址:18241896test01函数内修改可变类型全局变量a: [100, 200, 300, 400]test01函数内修改可变类型全局变量后a的地址:18241896test02函数内使用可变类型全局变量a: [100, 200, 300, 400]test02函数内使用可变类型全局变量a的地址:18241896

7、匿名函数


示例代码:

#匿名函数——lambda#语法:lambda arg1[,arg2...]:表达式    默认returnnum = lambda a,b:a+bprint(num(1,2))#运行结果:3

简单应用(一):

#四则运算——利用lambda表达式def operation(a,b,opt):    re = opt(a,b)    return renum1 = int(input("请输入第一个字符:"))num2 = int(input("请输入第二个字符:"))result = operation(num1,num2,lambda a,b:a+b)print(result)#运行结果:请输入第一个字符:2请输入第二个字符:35

简单应用(二):

#列表中的字典元素进行排序——lambda表达式students = [    {"name":"Joe","age":"18"},    {"name":"Tom","age":"20"},    {"name":"Susan","age":"16"}]students.sort(key=lambda x:x["name"])       #对字典按照关键字name排序print(students)#运行结果:[{'age': '18', 'name': 'Joe'}, {'age': '16', 'name': 'Susan'}, {'age': '20', 'name': 'Tom'}]

8、递归函数



代码示例:

#函数的嵌套def test1():    print("in test1...")def test2():    test1()    print("in test2...")def test3():    test2()    print("in test3...")test3()#运行结果:in test1...in test2...in test3...

#递归函数def func(n):    print("进入第%d层梦"%n)    if n ==3:        print("进入潜意识区")    else:        func(n+1)    print("从第%d层梦中醒来"%n)func(1)#运行结果:进入第1层梦进入第2层梦进入第3层梦进入潜意识区从第3层梦中醒来从第2层梦中醒来从第1层梦中醒来

应用:求阶乘

#阶乘——利用whilei = 1num = 1while i <= 4:    num = num*i    i+=1print(num)#阶乘——利用递归def func01(n):    if n ==1:        return 1    return n*func01(n-1)print(func01(4))#运行结果:2424

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


9、常用内置函数


示例代码:

#abs()——绝对值函数num = -1print(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 = 5print(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]263.148True4Hello

10、高阶函数


示例代码:

#常用高阶函数#map()num1 = map(lambda x:x*2,[1,2,3,4,5])print(num1)for i in num1:      #遍历map对象的内容    print(i,end=" ")print()#filter()num2 = filter(lambda x:x%2 == 1,[1,2,3,4,5,6,7,8,9,10])print(num2)for j in num2:      #遍历filter对象的内容    print(j,end=" ")print()#reduce()from functools import reduceprint(reduce(lambda x,y:x+y,[1,2,3,4],10))  #10是起始值#运行结果:<map object at 0x0059F730>2 4 6 8 10 <filter object at 0x0059F890>1 3 5 7 9 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 reduceman_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)def func(n,m):    #生成一个列表    people = list(range(1,n+1))    k = 0       #定义开始的索引    #开始循环报数    while len(people) > 2:        k = (k+(m-1))%len(people)        print("kill:",people[k])        del(people[k])        print(k)    return peopleprint(func(9,3))#运行结果:kill: 32kill: 64kill: 96kill: 42kill: 84kill: 52kill: 21[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 test1res = test()      #test函数返回值res是一个函数,等价于res ==> test1re = res()       #res() ==>test1()  ,test1函数返回值re是一个函数,re==>test2re()            #re() ==> test2()#运行结果:hello
(2)闭包:内部函数可以取到外部函数的局部变量

#闭包:内部函数可以取到外部函数的局部变量def test(x):    def test1(y):        def test2(z):            print(x+y+z)        return test2    return test1res = 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) = warpdef delete():    print("deleting...")delete()            #执行warp#运行结果:logger strating...deleting...logger ending...

(3)装饰器修饰有参数和返回值的函数

#装饰器修饰有参数、有返回值的函数def log(func):              #log(func)==> func = delete(delete函数作为实参传入到func)    def warp(*args,**kwargs):        print("logger strating...")        res = func(*args,**kwargs)          #运行delete        print(res)        print("logger ending...")    return warp@log   #用log来装饰delete,等价于delete = log(delete) = warpdef delete(name,age):    print("deleting...")    print(name,age)    return "delete success"delete("liu",20)            #执行warp#运行结果:logger strating...deleting...liu 20delete successlogger ending...

(4)装饰器自身带有参数

#装饰器带有参数def log(i):    def warp1(func):        def warp2(*args,**kwargs):            print("logger strating...")            if i>0:                print("logging success...")                func(*args, **kwargs)            else:                print("logging failed...")            print("logger ending...")        return warp2    return warp1@log(1)def delete():    print("deleting...")delete()#运行结果:logger strating...logging success...deleting...logger ending...

#装饰器带有参数def log(i):    def warp1(func):        def warp2(*args,**kwargs):            print("logger strating...")            if i>0:                print("logging success...")                func(*args, **kwargs)            else:                print("logging failed...")            print("logger ending...")        return warp2    return warp1@log(-1)def delete():    print("deleting...")delete()#logger strating...logging failed...logger ending...

15、迭代器

#!/usr/bin/env python# -*- coding:utf-8 -*-# Author:ZhengzhengLiu#迭代器——笛卡尔积import itertoolsx = 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)for h in coml4:    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')





原创粉丝点击