函数的概要
一、1、减少代码重复,2、方便修改,更易扩展,3、保持代码一致性
创建函数的规则:
1、函数代码块以 def 关键词开头,后接函数名称和圆括号
2、任何传入参数和变量放在圆括号
3、以冒号结束
4、代码块需缩进4个空格
函数的创建:
def 函数名(传参列表):#define的缩写def作为函数的关键字,定义的意思 函数体 def f(): print("ok") f() #调用函数,调用是后面一定要跟括号 输出结果: ok #光写一个f是一个变量名字,这是存的一条条的执行语句,之前变量存的是一个固定对象 print f #内存地址存的是 print("ok") 输出结果: <function print_info at 0x027575F0>
传入一个参数 def f(index): print("funciton %s"%index) f(1) #1传给了index 输出结果: function 1 f(2) #1传给了index 输出结果: function 2
传入两个参数 def add(a,b):#a,b是形参,不传值不占内存 print (a+b) add(3,4)#调用函数并传入两个参数(按顺序对应) ,a接收3,b接收7 输出结果: 7 形参多少个,实参我们就要传入多少个 add(3)#报错,需要传2个参数,你只传了1个 add(3,4,5)#报错,需要2个参数,你传入了3个
def print_info(name,age): print("name: %s"%name) print("age: %s"%age) 必须参数,以正确的顺序传入函数,调用时的数量必须和声明的一样 print_info("xiaohu",38)#调用函数,并传入2参数 输出结果: name: xiaohu age: 38 """ %s 可以接受int ,%d 不能接受string型 """ print_info(38,"xiaohu") #不能这样传,因为38是年龄,必需参数
关键字参数 def print_info(name,age): print("name: %s"%name) print("age: %d"%age) print_info(age = 39,name = "xiaohu")#有定义关键字,就没有顺序关系了
默认参数 def prnit_info(name,age,sex): print("Name: %s"%name) print("Age: %d"%age) print("Sex: %s"sex) pirnt_info("xiaohu",40,"male") print_info("jinxin",41,"male") print_info("wuchao",12,"male") #普遍是男性时,可以把sex默认为male #默认参数的放后边,默认参数在形参里面去加 def prnit_info(name,age,sex = "male"): print("Name: %s"%name) print("Age: %d"%age) print("Sex: %s"sex) #男性的时候就属于默认的,女性时给传female pirnt_info("xiaohu",40) print_info("jinxin",41) print_info("wuchao",12) print_info("lichun",18,"female")
不定长参数 def add(x,y,z): print(x+y+z) add(1,2,3) 以上这个加法器太low了,只能三位相加,如果有更多位怎么办? def add(*args):#参数前面一定要带个*号,代码的是现在接收的是一个不定长参数 print(args)#打印一个元组 add(1,2,3,4,5)#传一个元组 输出结果: (1,2,3,4,5) 多位数的加法器 def add(*args): sums = 0 for i in args: sums += i print (sums) add(1,2,3,4,5)#函数调用 输出结果: 14
接收不定长的有命名的参数 def print_info(name,age,sex,job):#这是一个定长的参数 print("name: %s"name) print("age: %d"%age) print("sex: %s") print("job: %s"%job) print_info("alex",18,"male",job="TT")#函数调用, 传入两种参数,一种没有名字,一种有名字 以下这种方式去接收参数,就没有接不到的,无名的*args接收,有名的**kwargs接收 例: def print_info(*args,**kwargs): #这是不定长无命名参数和不定长无命名参数 print(args)#接受的是无名字的值,一个元组形式 print(kwargs)#接收的是一个有名字的,键值对的,以一个字典形式 for i in kargs: print ("%S:%S"%(i,kwargs[i])) print_info("alex",18,"male",job="TT",hobby="girls")#函数调用 输出结果: ("alex",18,"male") {"job":"TT","hobby":"girls"} 关于顺序: def func(name,age="22",*args,*kwagrs) def func(关键字参数,默认参数,不定长无命名参数(元组),不定长有命名参数(字典))
需要打开文件,写入内容,关闭文件,重复多次操作 f = open("log.txt" , "a") f.write("2018-1-26 21:15 function1") f.close() f = open("log.txt" , "a") f.write("2018-1-26 21:15 function2") f.close()
楼上代码重复太多,减少代码的重复,可以使用函数 def logger(): f = open("log.txt","a") f.write(2018-1-26 21:15 function1) f.close() logger()#调用函数
楼上代码虽然使用函数减少了代码量,但是每次写入的内容都是一样的 我们需要每次写入不一样的内容,如何解决? 实例: def logger(log_text):#给函数设置形参,调用的时候传入值 f = open("log.txt","a") f.write(log_text) f.close() logger("2018-1-29 21:30,function1")#调用函数,并传入实参,每次调用可以传入不样的值 logger("2018-1-29 21:30,function2")#调用函数,并传入实参
def action1(n): #功能1 print ("starting action1……) with open("日志记录","a") as f: f.write("end action %s "%n) def action2(n):#功能2 print(starting action2……) with open("日志记录","a") as f: f.wirte("end action %s "%s) 重复代码,打开日志记录,写入日志,我们需要把这一部份提出来写成一个函数 日志记录,最重要的是时间我们要加个时间进去,把记录时间加在logger函数内。 这就保持扩展性(在一个函数内扩展),和一致性(格式一致) import time def logger(n): time_format = "%Y-%m-%d %H:%M:%S" #时间的格式 time_current = time.strftime(time_format)#当前时间 with open("日志记录","a") as f: f.write("%s end action %s "%(time_current,n)) def action1(n): #函数里面调用函数 print("starting action1……") logger(n) def action2(n): print ("starting action2……") logger(n)
return
return的作用 def f(): print("ok") return 1 #作用 1、结束函数,2、返回某个对象 print ("ok1")#这句没任何意思了,因为前面就结束了 返回什么内容,给谁呢? a = f() print (a) 输出结果: 1 ------------------------------------------------------- def f(): print ("ok") #没有return返回值,自动返回一个None(系统默认) d = f() print (d) 输出结果: None ------------------------------------------------------ 例: def add(*args): sums = 0 for i in args: sums += i return sums #不加返回值,就会默认返回None dd = add(1,3,5,7,9) print dd 输出结果: 25 ---------------------------------------------------- def foo(): return 1,"123",8 #return多个对象 print (foo()) 输出结果: (1,"123",8)# 返回的是一个元组 注意: 要想获取函数执行的结果,就用return语句把结果返回 1、函数如果没有return 会默认返回一个None 2、如果retrun 多个对象,python会帮我们把多个对象封装成一个元组返回 3、函数执行过程中遇到return,就会停止执行,并返回结果。return就代表着函数结束
函数的作用域
函数的作用域 def f():函数有自己的作用域 a = 10 #仅在函数里面有作用,出了这个函数就没有了 print (a) 报错提示a没有被定义 -------------------------------------------- 最外层built_in ,里面一层global,再往里一层enclosing ,最里面一层local 顺序从里到外 (global ,nonlocal 都是为了改外部变量进行一个修改用的) x = int(2.85) #系统固定模块里面的变量。 g_count = 0#全局作用域 def outer(): o_outer = 1 #嵌套作用域 def inner(0: i_count = 2#局部作用域 print(i_count) outer() ----------------------------------------------------- count = 10 def outer(): print (count) count = 5 #全局变量在局变量变是不可以修改的,你只可以看 print (count) outer() 输出结果: 报错,不能修改全局变量 --------------------------------------------------- count = 10 def outer(): #print count 注释掉这一行 count = 5 #这样就可以,相当于重新定义了一个count print (count) outer()#调用函数 输出结果: 10 ------------------------------------------------ 想要在局部变量修改全局变量,加一个global count = 10 def outer(): global count #声明是全局变量 print (count) count = 1 print (count) outer()#调用函数 输出结果: 10 1 ------------------------------------------------- 局部修改嵌套变量(第二层),python3新加的功能nonlocal def outer(): count = 5 def inner(): nonlocal count print (count) count = 10 print (count) inner() print (count) outer()
递归函数
什么是递归函数?
1、可以调用函数本身
2、有一个结束条件
3、递归能做的事情循环都可以解决
例一、
不使用递归,1+2+3+...100=? i = 1 sums = 0 for i in range(100): sums = sums +i print sums 输出结果: 5050
使用递归函数
def sum(n): if n == 1: return 1 return n+sum(n-1) print sum(100) 输出结果: 5050
例二、
不用递归
def fib(max): n,b,a = 0,0,1 while n<max: print b b,a = a,a+b n +=1 fib(8) 输出结果: 0 0 1 1 2 3 8 13 21
用递归 #斐波那契规则0,1,1,2,3,5,8,13,21 def fib(n): # if n == 1 or n == 0: return n return fib(n-1) + fib(n-2)#减的是下标的位置 print fib(6)#下标为6的数是8,8前面一位是5,8前面两位是3。所以是5+3=8 print fib(4)#下标为4的数是3,3前面一位是2,8前面两位是1,所以是2+1=3 输出结果: 8 3
list = []#把获取的斐波拉契数字存放到列表中 for i in range(0,20): list.append(fib(i)) print list
输出结果
[0, 1, 1, 2, 3, 5, 8, 13, 21]
def fibs(n):
list = []
for i in range(n+1):
list.append(fib(i))
return list
print fibs(10)
输出结果:
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]