一、函数:函数定义关键字def 后跟函数名称
def
函数名(参数):
...
函数体
...
返回值
案例:
# 定义函数
def say_hei():
print('hello world!!') # 函数调用
say_hei()
调用函数
函数的调用:函数名加括号
1 先找到名字
2 根据名字调用代码
函数的定义主要有如下要点:
- def:表示函数的关键字
- 函数名:函数的名称,日后根据函数名调用函数
- 函数体:函数中进行一系列的逻辑计算,如:发送邮件、计算出 [11,22,38,888,2]中的最大数等...
- 参数:为函数体提供数据
- 返回值:当函数执行完毕后,可以给调用者返回数据。
二、参数
函数的有三中不同的参数:
- 普通参数
-
# ######### 定义函数 ######### # name 叫做函数func的形式参数,简称:形参
def func(name):
print('%s hello!'%name) # ######### 执行函数 #########
# 'zhangsan' 叫做函数func的实际参数,简称:实参
func('zhangsan') - 默认参数
-
def func(name, age = 18): print("%s:%s" %(name,age)) # 指定参数
func('zhangsan', 19)
# 使用默认参数
func('lisi') 注:默认参数需要放在参数列表最后 - 动态参数
def func(*args):
print (args) # 执行方式一
func(11,33,4,4454,5) # 执行方式二
li = [11,2,2,3,3,4,54]
func(*li)
def func(**kwargs): print (args) # 执行方式一
func(name='zhangsan',age=18) # 执行方式二
li = {'name':'zhangsan', age:18, 'gender':'male'}
func(**li)
def func(*args, **kwargs): print(args)
print(kwargs)
内置函数
函数分类
#1、内置函数
为了方便我们的开发,针对一些简单的功能,python解释器已经为我们定义好了的函数即内置函数。对于内置函数,我们可以拿来就用而无需事先定义,如len(),sum(),max()
ps:我们将会在最后详细介绍常用的内置函数。 #2、自定义函数
很明显内置函数所能提供的功能是有限的,这就需要我们自己根据需求,事先定制好我们自己的函数来实现某种功能,以后,在遇到应用场景时,调用自定义的函数即可。例如
函数使用的原则:先定义,再调用
函数即“变量”,“变量”必须先定义后引用。未定义而直接引用函数,就相当于在引用一个不存在的变量名
#测试一
def test():
print('from test')
func()
test() #报错 #测试二
def func():
print('from func')
def test():
print('from test')
func()
test() #正常 #测试三
def test():
print('from test')
func() def func():
print('from func')
test() #会报错吗? #结论:函数的使用,必须遵循原则:先定义,后调用
#我们在使用函数时,一定要明确地区分定义阶段和调用阶段 #定义阶段
def test():
print('from test')
func()
def func():
print('from func')
#调用阶段
test()
函数的嵌套调用
def testB():
print('---- testB start----')
print('这里是testB函数执行的代码...(省略)...')
print('---- testB end----') def testA(): print('---- testA start----') testB() print('---- testA end----') testA()
结果:
---- testA start----
---- testB start----
这里是testB函数执行的代码...(省略)...
---- testB end----
---- testA end----
小总结:
- 一个函数里面又调用了另外一个函数,这就是所谓的函数嵌套调用
- 如果函数A中,调用了另外一个函数B,那么先把函数B中的任务都执行完毕之后才会回到上次 函数A执行的位置
应用
# 求3个数的和
def sum3Number(a,b,c):
return a+b+c # return 的后面可以是数值,也可是一个表达式 # 完成对3个数求平均值
def average3Number(a,b,c): # 因为sum3Number函数已经完成了3个数的就和,所以只需调用即可
# 即把接收到的3个数,当做实参传递即可
sumResult = sum3Number(a,b,c)
aveResult = sumResult/3.0
return aveResult # 调用函数,完成对3个数求平均值
result = average3Number(11,2,55)
print("average is %d"%result)
局部变量
- 局部变量,就是在函数内部定义的变量
- 不同的函数,可以定义相同的名字的局部变量,但是各用个的不会产生影响
- 局部变量的作用,为了临时保存数据需要在函数中定义变量来进行存储,这就是它的作用
全局变量
# 定义全局变量
a = 100 def test1():
print(a) def test2():
print(a) # 调用函数
test1()
test2()
全局变量和局部变量名字相同问题
修改全局变量 关键字:global
- 在函数外边定义的变量叫做
全局变量
- 全局变量能够在所有的函数中进行访问
- 如果在函数中修改全局变量,那么就需要使用
global
进行声明,否则出错 - 如果全局变量的名字和局部变量的名字相同,那么使用的是局部变量的,小技巧
强龙不压地头蛇
可变类型的全局变量
>>> a = 1
>>> def f():
... a += 1
... print a
...
>>> f()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in f
UnboundLocalError: local variable 'a' referenced before assignment
>>>
>>>
>>> li = [1,]
>>> def f2():
... li.append(1)
... print li
...
>>> f2()
[1, 1]
>>> li
[1, 1]
- 在函数中不使用global声明全局变量时不能修改全局变量的本质是不能修改全局变量的指向,即不能将全局变量指向新的数据。
- 对于不可变类型的全局变量来说,因其指向的数据不能修改,所以不使用global时无法修改全局变量。
- 对于可变类型的全局变量来说,因其指向的数据可以修改,所以不使用global时也可修改全局变量。
递归函数
如果一个函数在内部不调用其它的函数,而是自己本身的话,这个函数就是递归函数。
看阶乘的规律
1! = 1
2! = 2 × 1 = 2 × 1!
3! = 3 × 2 × 1 = 3 × 2!
4! = 4 × 3 × 2 × 1 = 4 × 3!
...
n! = n × (n-1)!
原理
匿名函数
用lambda关键词能创建小型匿名函数。这种函数得名于省略了用def声明函数的标准步骤。
lambda函数的语法只包含一个语句,如下:
lambda [arg1 [,arg2,.....argn]]:expression
例题
sum = lambda arg1, arg2: arg1 + arg2 #调用sum函数
print ("Value of total : ", sum( 10, 20 ))
print ("Value of total : ", sum( 20, 20 ))
# 匿名函数 关键字:lambda
l = lambda x: x + 1
print(l(5))
print("=================== map函数==============")
jia = lambda x: x + 1;
jian = lambda x: x - 1
chen = lambda x: x * 1
chu = lambda x: x / 1 def map_text(func, array):
arr1 = []
for i in array:
f = func(i)
arr1.append(f)
return arr1 arr = [1, 2, 3, 4, 5]
new_array = map_text(lambda x: x - 1, arr)
print(new_array)
print("=================== filter函数==============") def filter_text(func, array):
new_array = []
for i in array:
if func(i):
new_array.append(i)
return new_array str_array = ['zhangsan_sb', 'lisi_sb', 'wanger', 'mazi']
s = filter_text(lambda x: x.endswith('sb'), str_array)
print(s)
print("=================== reduce函数==============") def reduce_text(func, array, init=None):
if init is None:
sum = array.pop(0)
else:
sum = init
for i in array:
sum = func(sum, i)
return sum int_array = [1, 2, 3, 4, 5, 6, 7, 8, 9]
su = reduce_text(lambda x, y: x + y, int_array)
print(su)
闭包函数
#内部函数包含对外部作用域而非全局作用域的引用 #提示:之前我们都是通过参数将外部的值传给函数,闭包提供了另外一种思路,包起来喽,包起呦,包起来哇 def counter():
n=0
def incr():
nonlocal n
x=n
n+=1
return x
return incr c=counter()
print(c())
print(c())
print(c())
print(c.__closure__[0].cell_contents) #查看闭包的元素
闭包的意义与应用
#闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域
#应用领域:延迟计算(原来我们是传参,现在我们是包起来)
from urllib.request import urlopen def index(url):
def get():
return urlopen(url).read()
return get baidu=index('http://www.baidu.com')
print(baidu().decode('utf-8'))