以下方法均在python解释器中进行了测试,读者复制代码时,记得去掉注释符。
#!/usr/bin/env python # -*- coding: utf-8 -*- # ******************************一:函数的定义和目的****************************** # 函数的格式如下: # def 函数名(参数1,参数2,参数3....参数n): # 函数体 #定义: # 1:"def"为函数的开始,在声明建立函数时一定要用def;def所在的这一行被称为函数头; # "test"为函数名称,注意名称最好要有一定意义,比如可以从名称看出来函数作用; # "(a,b)"为参数列表,通常称为形参; # ":"注意冒号,表示函数头结束; # 2: "c = a + b"从这一行起就是函数体,函数体是缩进了4个空格的代码块 # 3:"return" 是函数的关键字,意思是返回一个值;return作用:1:返回一个值;2:结束函数的运行,并返回到调用这个函数的地方 # 4:"res = add_fun(2,3)"调用函数,并传入两个参数(实参) # def add_fun(a,b): # c = a + b # return c # res = add_fun(2,3) # 目的: # 1:降低编程难度 2:代码重用 3:实现特定功能 # ******************************二:函数的参数****************************** # 参数分为位置参数,关键字参数和参数组 # 1:位置参数: "4,5"就是位置参数,在调用函数时,位置参数,必须一一对应,缺一不行多一也不行 # def add_fun(x,y): # return x+y # print(add_fun(4,5)) # 2:关键字参数:"y=10,x=5"就是关键字参数在调用函数时,关键字参数,无须一一对应,缺一不行多一也不行 # def add_fun(x,y): # return x+y # print(add_fun(y=10,x=5)) # 注意:关键字参数必须在位置参数的右侧 # def add_fun(x,y,z): # return x+y+z # print(add_fun(10,z=10,y=5)) # 3:默认参数:"z=5"就是默认参数,调用函数时默认参数可以不传值,也可以传值 # def add_fun(x,y,z=5): # return x+y+z # print(add_fun(10,y=10)) # 4:参数组:*args,**kwargs就是参数组,一般**对应字典,*对应元组;参数组可以传入多个值 # def test(a,*args,**kwargs): # "*"表示参数的参数不受个数的限制 # print(a) #将1传给a # print(args) #将(2, 'hello', 'qwer', 4, 5, 6)作为一个整体,以元组的形式传给args # print(kwargs) #将{'name': 1, 'x': 666}作为一个整体,以字典的形式传给kwargs # test(1,2,"hello","qwer",4,5,6,name=1,x=666) # def test(x,*args): # print(args,type(args)) # test(1,*[11,22,33]) #加*号,将*号里面的每一个元素传给args,将11, 22, 33,"qwer"作为元组的元素传给args # test(1,*(11,22,33)) # test(1,[11,22,33]) #不加*号,将[11,22,33]作为元组的第一个元素传给args # test(1,(11,22,33)) # def test(x,*args,**kwargs): # print(args, type(args)) # print(kwargs,type(kwargs)) # test(1,[2,3,4],name="ae",age=18) # test(1,*[2,3,4],**{"name":"ae","age":18}) # ******************************三:函数的变量****************************** # 变量分为局部变量和全局变量; # 1:局部变量:在子程序中定义的变量称为局部变量,其作用域是定义该变量的子程序; 局部变量变量名最好小写 # def test(b): # a = 1 #此时a=1就是局部变量 # c = a + b # print(c) # test(11) # 2:全局变量:在程序的一开始定义的变量称为全局变量,其作用域是整个程序;全局变量变量名最好用大写 # 注意:当全局变量与局部变量同名时:在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用 # a = 10 #此时a=10是全局变量 # def test(b): # a = 1 #此时a=1就是局部变量 # c = a + b # print(c) # test(11) #由于函数内部有局部变量a=1,结果输出12 # 3:global关键字和nonlocal关键字 # 3.1 global关键字:适用于在函数内部声明全局变量,或者修改全局变量的值 # li = [1,2,3] # def test(): # global li #将全局变量li=[1,2,3]的引用传入到函数中(引用相当于门牌号) # print(li) # test() # print(li) # li = [1,2,3] # def test(): # global li #将全局变量li=[1,2,3]的应用传入到函数中(引用相当于门牌号) # li = 100 #将li=[1,2,3]修改为li=100,及函数内部通过global关键字修改全局变量li # print(li) # test() # print(li) # 注意:函数参数传的对象的引用,即就是传的是变量的门牌号 # 优先读取局部变量li,如果没有局部变量li,则会向上一层寻找变量li;如果li是可变类型对象,就算没有global关键字,也可以直接修改li的内容 # li = [1,2,3] # def test(): # # global li #有没有global关键字,输出的结果是一样的 # li.append(99) #向li添加元素99,由于列表是可变类型对象,所以即使没有局部 # print(li) # test() # print(li) # 3.2 nonlocal关键字:适用于嵌套函数中内部函数修改外部函数中变量的值 # li = [1,2,3] # # def test(): # # a =100 # # print("这个是test函数的值", a) # # def test1(): # # nonlocal a #类似于global关键字,也可以修改上一级变量中的值 # # print("这个是test1函数",a) # # test1() # # test() # ******************************四:函数的返回值****************************** # 函数的返回值就是:函数向调用函数的地方返回的数据;关键字return后面的就是函数的返回值 # return 关键字的作用: # 1. 向调用函数的地方返回的数据 # 2. 结束函数的执行 #注意:1.当一个函数/过程没有使用return显示的定义返回值时,python解释器会隐式的返回None, # 2.过程与函数的区别就是过程是没有返回值的函数 # 3.函数的返回值可以有多个:返回值数=0:返回None # 返回值数=1:返回object # 返回值数>1:返回tuple # def add_fun(a,b): # c = a+b # res = add_fun(2,3) # print(res) #没有return关键字时,返回值默认为None;返回值数=0:返回None # def add_fun(a,b): # c = a+b # return c # res = add_fun(2,3) # print(res) #返回值数=1:返回object # def add_fun(a,b): # c = a+b # return a+b,a**b,a*b # res = add_fun(2,3) # print(res,type(res)) #返回多个值时用逗号隔开返回值数>1:返回tuple # ******************************五:函数的递归****************************** # 函数递归定义:如果在调用一个函数的过程中直接或间接调用自身的行为称为递归 # 递归特性: # 1. 必须有一个明确的结束条件 # 2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少 # 3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用, # 栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出) # 求一个数的阶乘 # def factorial(n): # if n==1: # print("1的阶乘结果为1") # return 1 # else: # res = n*factorial(n-1) #调用自身 # print("{}的阶乘结果为:{}".format(n,res)) # return res # factorial(20) # ******************************六:函数的嵌套****************************** # 函数嵌套定义:在定义一个函数时,在函数体内部再次定义另一个函数称为嵌套 # def add_fun(a,b): # res =a+b # print("这个是add_fun函数","相加结果为:",res) # def sub_fun(a,b): #此时a,b为add_fun函数所传的参数,详情参考函数的变量部分 # res = a - b # print("这个是sub_fun函数", "相减结果为:", res) # sub_fun(a,b) # add_fun(100,99) # ******************************七:函数的传递****************************** # 函数的传递:将函数当做一个变量进行传递,即就是函数即变量 # def pingfang(n): # res = n**2 # return res # def li(pingfang,li): #将函数当做一个变量进行传递,在另一个函数中进行调用 # res = [] # for i in li: # s= pingfang(i) # res.append(s) # print("这个是li函数,{}中元素的平方结果为:".format(li),res) # return res # li(pingfang,[1,2,3,4,5]) # ******************************八:函数的作用域****************************** # 作用域:变量产生作用的区域称为作用域; # 作用域分为:1:局部作用域(也称为本地作用域);2:嵌套作用域;3:全局作用域;4:内建作用域 # python按照从前到后的顺序在作用域中查找变量 # 注意: 1:作用域在定义函数时就已经固定住了,不会随着调用位置的改变而改变 # 2:变量的作用域在函数或者类中才能被改变 # def out_test(): # a = 10 #a=10为局部变量 # def in_test(): # print("这个是in_test函数,a={}".format(a)) #由于没有局部变量a,所以此时向上一级嵌套作用域中查找a=10 # in_test() # print("这个是out_test函数,a={}".format(a)) # # a = 999 #a=999为全局变量 # out_test() # print("a=",a) # ******************************九:函数式编程与高阶函数****************************** # 三种编程方法:1.面向过程;2.函数式编程;3.面向对象 # 用编程语言定义的函数来实现数学上的函数,即就是用编程语言来实现数学模型 # 函数式编程特点:代码少,但是不便于理解 # y = x**2 + 5*x +18 数学模型 # def test(x): # return x**2 + 5*x +18 # print(test(1)) # 高阶函数定义:满足任意两个特性任意一个即为高阶函数:1.函数的传入参数是一个函数名;2.函数的返回值是一个函数名 # 1.函数的传入参数是一个函数名 # def test(fun): #函数的传入参数是一个函数名 # fun() # print("这个是test函数") # def example(): # print("这个是example函数") # test(example) # 2.函数的返回值是一个函数名 # def test(): # print("test") # def example(): # print("example") # return test #函数的返回值是一个函数名 # a = example() #将example函数的返回值赋值给a # a() #执行a(),相当于执行test() # ******************************十:常用的几种特殊函数****************************** # 1.lambda函数:也叫匿名函数; # 注意:1.lambda后面直接跟变量;2.变量后面是冒号;3.冒号后面是表达式,表达式的计算结果就是本函数的返回值 # 计算一个数的平方 # def pingfang(x): # y = x**2 # return y # print(pingfang(20)) # f = lambda x:x**2 #这一句等同于函数pingfang() # print(f(20)) # 2.map函数:对可迭代对象中的每一个元素进行相同的逻辑操作并返回一个迭代器(对元素进行上下运算) # 使用方法:1.括号里面先是逻辑操作(也可以是函数名);2.逻辑操作后面是逗号;3.逗号后面是要处理的对象(注意该对象必须是可迭代对象) # 注意事项:1.对可迭代对象中的每个元素进行逻辑操作;2.将所有结果返回一个map对象,这个对象是迭代器 # 计算列表中数字的平方 # def pingfang(x): # y = x**2 # return y # li = [1,2,3,4] # print(list(map(pingfang,li))) # print(list(map(lambda x:x**2,li))) # 注意事项:3.如果参数很多,则对参数并行执行逻辑操作 # l1 = [12,23,34,45,33] # l2 = [22,33,44,55] # l3 = [11,22,33,44] # l4 = [99,88,77,66] # s =map(lambda x,y,z,s:x+y+z+s,l1,l2,l3,l4) # print(list(s),type(s)) # 3.reduce函数:对可迭代对象中的每一个元素进行相同的逻辑操作并返回一个迭代器(对元素进行横向运算) # 使用方法:1.括号里面先是逻辑操作(也可以是函数名);2.逻辑操作后面是逗号; # 3.逗号后面是要处理的对象(注意该对象必须是可迭代对象);4.后面是初始值 # 注意事项:1.在python3中,reduce()已经被移到funtools模块里面,使用reduce()需要导入funtools模块 # 计算列表中数字的积 # from functools import reduce # li = [12,34,56,78,90] # def add_fun(x,y): # return x*y # print(reduce(add_fun,li,1)) # print(reduce(lambda x,y:x*y,li,1)) # 4.filter函数:对可迭代对象中的每一个元素进行条件判断,满足判断条件的元素则进行返回 # 使用方法:1.括号里面先是逻辑判断(也可以是函数名);2.逻辑判断后面是逗号;3.逗号后面是要处理的对象(注意该对象必须是可迭代对象) # 注意事项:1.对可迭代对象中的每个元素进行逻辑判断;2.将满足条件的结果返回一个filter对象,这个对象是迭代器 # 判断列表中数字大于5的元素 # li = [1,2,67,88,99] # s = filter(lambda x:x>5,li) # print(list(s),type(s))