1. 函数(functin),什么是函数,就是将一些语句通过一个名字去代替,通过调动函数名来实现其功能
对于我们以前写的那些三级菜单以及购物车程序,中间是有一部分比较重复的过程,看起来比较繁琐每次调用都需要去写那些,所以呢我们可以把这些重复的代码用一个东西来代表一下即函数,然后再去调用,这样就方便了很多,因此,这里我介绍一下基本的函数用法,
1.1 特性 :一致性 可扩展性 代码重用
1.2 格式,在python中用函数定义一般是def(define) 通过def来定义的,格式如下
def ( ) ()内是函数名
函数体 如下举个例子
1 def f(): 2 print("sang") 3 f()
1 sang
1.3 函数的命名规则和变量的命名规则差不多
函数名必须以下划线或字母开头,可以包含任意字母、数字或下划线的组合。不能使用任何的标点符号; 函数名是区分大小写的。 函数名不能是保留字。
1.4 参数
形参和实参,关键字参数,必须参数,默认参数,形参,不是实际存在的是虚拟的,在定义的时候使用形参,如f(),实参,是在调用的时候传递给函数的参数,我通过例子来说明
1.4.1
def f(n): 形参 print(x) f(33) 实参
1 def action1(n): 2 print("start action1...") 3 def action2(n): 4 print("start action2...") 5 def action3(n): 6 print("start action3...") 7 action1(1) 8 action2(2) 9 action3(3)
结果:
1 start action1... 2 start action2... 3 start action3...
1.4.2一个日志记录
1 import time 2 def logger(n): 3 time_format = "%Y-%m-%d %X" 4 time_current = time.strftime(time_format) 5 with open("日志记录","a")as f: 6 f.write("%s end action%s "%(time_current,n)) 7 def action1(n): 8 print("start action1...") 9 logger(n) 10 def action2(n): 11 print("start action2...") 12 logger(n) 13 def action3(n): 14 print("start action3...") 15 logger(n) 16 action1(1) 17 action2(2) 18 action3(3)
结果:
start action1...
start action2...
start action3...
还有在新建的文件里面我们会发现时间
2016-09-06 11:25:46 end action1
2016-09-06 11:25:46 end action2
2016-09-06 11:25:46 end action3
1.4.3必须和关键字参数
1 def print_info(name,age): 2 print("Name:%s"%name) 3 print("Age:%d"%age) 4 print_info("sang",22) #必需参数 就是顺序得一致,调用和声明的顺序得一样 5 print_info(name="sang",age = 22) #关键字参数 如果是print_info(22,"sang")就会报错了
结果:
1 Name:sang 2 Age:22 3 Name:sang 4 Age:22
1.4.4 默认参数
1 #默认参数 2 def print_info(name,age,sex = "male"): 3 print("Name:%s"%name) 4 print("Age:%d"%age) 5 print("Sex:%s"%sex) 6 print_info(name = "sang",age = 22) 7 print_info("jinxin",25) 8 print_info("wuchao",26) 9 print_info("lili",27,"female")
结果:
Name:sang Age:22 Sex:male Name:jinxin Age:25 Sex:male Name:wuchao Age:26 Sex:male Name:lili Age:27 Sex:female
1.4.5不定长参数 :
1 def add(x,y): 2 print(x+y) 3 add(5,9) 4 5 def add(x,y,z): # 这种方法有点LOW 6 print(x+y+z) 7 add(1,2,3)
我们计算几个数的加法运算,但是如果好多数呢,显然这种方法就不行了,所以呢就引入了不定长参数*args **kwargs
1 def add(*args): 2 print(args) 3 sum = 0 4 for i in args: 5 sum +=i 6 print(sum) 7 add(1,2,3,4,5,6,7,8,9)
结果是
(1, 2, 3, 4, 5, 6, 7, 8, 9)
45
这样就实现个多个数的运算,*args表示没有命名的变量参数,**kwargs表示已经命名的变量参数
1 def f(**kargs): 2 print(kargs) 3 4 f(**{'name':'sang'})
{'name': 'sang'}
1 def print_info(*args,**kwargs): 2 print(args) 3 print(kwargs) 4 for i in kwargs: 5 print("%s:%s"%(i,kwargs[i])) 6 print_info() 7 print_info("aaa",2,name = "hello")
结果是:
() {} ('aaa', 2) {'name': 'hello'} name:hello
1.46 高阶函数 一个或者多个函数可以作为输入,输出一个函数
1 def foo3(): 2 def inner(): 3 return 8 4 return inner 5 ret = foo3() 6 print(ret) 7 print(ret())
结果是:
<function foo3.<locals>.inner at 0x0000006435B6C598> 8
#1 函数名可以进行赋值
#2 函数名可以作为函数参数,还可以作为函数的返回值
1 def f(n): 2 return n*n 3 def foo(a,b,func): 4 ret=func(a)+func(b) 5 return ret 6 print(foo(1,2,f))
结果:
5
2. 函数的返回值 return
1 #-author:"sangshijia" 2 #date: 2016/9/5 3 def f(): 4 print("OK") 一般情况下是默认返回一个None的,也可以写出来 5 return 10 # 结束函数返回某个对象 6 a=f() 7 print(a) #print(f())
3.函数的作用域
我们可以通过下面的代码来 弄清它们之间的位置和关系
1 #作用域它们之间的关系如下:作用域局部local>外层作用域enclosing>当前模块中的全局global>python内置作用域built_in,也就是LEGB。 2 a = int(3.2) #built-in 系统固定的模块里变量 如 int等 3 count = 10 # 全局变量global 4 def outer(): 5 o_count = 1 # 嵌套的局部变量 enclosing 6 print(o_count) 7 #count = 5 8 def inner(): 9 i_count = 3 # local 局部变量 10 print(o_count) 11 print(i_count) 12 inner() 13 outer()
4.递归函数( recursion) 我的理解:在一个函数内部可以调用其他函数,但是如果调用(return)其函数本身,那么就是递归函数
1 #递归的特性: 1.调用自身函数, 2.有一个结束条件 2 #递归的效率有时候会很低
4.1 以 斐波那契数列 (0,1,1,2,3,5,8,13,21,34........)为例子
1 import time #还可以通过时间来 测出时间差 2 t1 = time.time() 3 def fibo(n): 4 before = 0 5 after = 1 6 if n == 0 or n ==1: 7 return n # 8 if n <= 3: 9 return 1 10 return fibo(n-1)+fibo(n-2) #递归 11 n = int(input(":")) 12 print(fibo(n)) 13 t2 = time.time() 14 print(t2 - t1)
结果是:
:3 1 5.416621446609497
1 # def fibo_new(n): 2 # if n <= 1: 3 # return 1 4 # return (fibo_new(n - 1) + fibo_new(n - 2)) 5 # 6 # print(fibo_new(6))
结果是:
13
4.2
def fibo_new(n): if n <= 1: return 1 return fibo_new(n-1)+fibo_new(n-2) print(fibo_new(3))
阶乘的例子:以5位例
1 def f(jiecheng): 2 for i in range(1, jiecheng): 3 jiecheng *= i 4 return jiecheng 5 print(f(5))
1 def fat(n): 2 ret=1 3 for i in range(2,n+1): 4 ret=ret*i 5 return ret 6 print(fat(5))
1 def fact(n): 2 if n==1: 3 return 1 4 return n*fact(n-1) 5 print(fact(5))
4.3 all 和eval函数
1 print(all("123456")) #all函数返回true,其他情况都是返回false 2 print(eval("1+3*5")) #而Python中的eval函数可以计算Python表达式,并返回结果
结果是:
True
16
4.4
str = ["a","b","c","d"] def funl(s): if s != "a": return s ret = filter(funl,str ) print(ret) print(list(ret)) #ret是一个迭代器对象
结果:
<filter object at 0x0000006CADCAB6D8> ['b', 'c', 'd']
重要内置函数:
1 def fun1(s): 2 if s != 'a': 3 return s 4 ret = filter(fun1, str)# ('b','c','d',) 5 print(ret) #<filter object at 0x0000000000A3A6A0> 6 print(list(ret)) # ret是一个迭代器对象
结果:
1 <filter object at 0x000000DF55C0B6D8> 2 ['b', 'c', 'd']
4.5其他几个函数的延伸
4.51 map
1 str = ["a","b","c","d"] 2 def fun2(s): 3 return s + "hello" 4 ret = map(fun2,str) #
注意filter与map的区别
print(ret) # map object的迭代器
5 print(list(ret))
结果:
<map object at 0x0000003A8780B6D8>
['ahello', 'bhello', 'chello', 'dhello']
1 from functools import reduce 2 def add1(x, y): 3 return x + y 4 5 print(reduce(add1,range(1,101)))#reduce 的结果就是一个值
5050
4.52
1 from functools import reduce 2 def add1(x,y): 3 return x + y 4 print(reduce(add1,range(1,101)))
结果为
5050
4.53 lambda 匿名函数
匿名函数的命名规则,用lamdba 关键字标识,冒号(:)左侧表示函数接收的参数(a,b) ,冒号(:)右侧表示函数的返回值(a+b)。
因为lamdba在创建时不需要命名,所以,叫匿名函数
def add(a,b): return a + b lambda a,b:a+b
匿名函数与正常函数的区别
def add(a,b):
return a+b
print(add(2,3))