函数
一,什么是函数?
函数就是事先定义一个事情或者功能。等到用的时候 直接用就好了。这里定义的东西就是一个函数
比如约会定义了一个动作或者功能
# define 函数定义
#def yue():
print("打开手机")
print("打开陌陌")
# 可以终止一个函数执行
return "大妈", "阿姨", "嫂子","姑娘" #函数的返回值
print("搜索一下你心仪的对象")
print("走吧. 出去玩啊")
print("出发!")
yue() #函数调用
二, 函数的定义
def 函数名()
函数体
函数名()
例如
#函数定义 def mylen(): """计算s1的长度""" s1 = "hello world" length = 0 for i in s1: length = length+1 print(length) #函数调用 mylen()
def 关键词开头,空格之后接函数名称和圆括号(),最后还有一个":"。 def 是固定的,不能变,他就是定义函数的关键字。
函数名的命名规则跟变量的命名规则一样。
三,函数的返回值。
执行完函数之后,我们可以使用return来返回结果
1 函数中越到return,此函数结束,不再继续执行 返回None
def yue(): print("约你") print("约我") print("约他") return print("约谁啊") #这句话不会执行 yue()
2 返回一个值
def mylen(): s = "hello python" length = 0 for i in s: length = length + 1 return length str_len = mylen() print('str_len: %s' %str_len)
3 返回多个值 多个返回值接收到的是元组
def yue(): print("打开手机") print("打开陌陌") # 可以终止一个函数执行 return "大妈", "阿姨", "嫂子","姑娘" print("搜索一下你心仪的对象") print("走吧. 出去玩啊") print("出发!") # 多个返回值接收到的是元组 ret = yue() print(ret)
四,函数的参数。
1. 实参:
1. 位置参数, 按照形参的参数位置, 给形参传值
2. 关键字参数, 按照形参的名字给形参传值
3. 混合参数. 即用位置参数, 也用关键参数
2. 形参:
1. 位置参数
2. 默认值参数 先位置后默认值
3. 动态参数
def mymax(x,y): #此时x=10,y=20 the_max = x if x > y else y return the_max ma = mymax(10,20) print(ma) 按照位置传参
def mymax(x,y): #此时x = 20,y = 10 print(x,y) the_max = x if x > y else y return the_max ma = mymax(y = 10,x = 20) print(ma) 按照关键字传参
def mymax(x,y): #此时x = 10,y = 20 print(x,y) the_max = x if x > y else y return the_max ma = mymax(10,y = 20) print(ma) 混合传参
站在形参角度
位置参数必须传值
def mymax(x,y): #此时x = 10,y = 20 print(x,y) the_max = x if x > y else y return the_max #调用mymax不传递参数 ma = mymax() print(ma) #结果 TypeError: mymax() missing 2 required positional arguments: 'x' and 'y'
def stu_info(name,sex = "male"): """打印学生信息函数,由于班中大部分学生都是男生, 所以设置默认参数sex的默认值为'male' """ print(name,sex) stu_info('alex') stu_info('eva','female') 默认参数
函数的动态参数
1. *args 位置参数动态传参
2. **kwargs 关键字参数动态传参
顺序:位置参数, *args, 默认值, **kwargs
def func(*args, **kwargs):
pass
形参的位置*,**: 聚合
实参的位置*,**: 打散
参数调用顺序
位置参数》*args》默认值参数》**kwargs
五,函数的命名空间
1. 内置名称空间
2. 全局名称空间
3. 局部名称空间
*内置命名空间中存放了python解释器为我们提供的名字:input,print,str,list,tuple...它们都是我们熟悉的,拿过来就可以用的方法。
加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)
取值顺序:
在局部调用:局部命名空间->全局命名空间->内置命名空间
在全局调用:全局命名空间->内置命名空间
综上所述,在找寻变量时,从小范围,一层一层到大范围去找寻。
作用域
作用域就是作用范围,按照生效范围可以分为全局作用域和局部作用域。
全局作用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效
局部作用域:局部名称空间,只能在局部范围内生效
globals和locals方法
globals 全局作用域 的内容
locals 当前作用域的内容
global关键字,nonlocal关键字。
global:
1,声明一个全局变量。
2,在局部作用域想要对全局作用域的全局变量进行修改时,需要用到 global(限于字符串,数字)
nonlocal:
1,不能修改全局变量。
2,在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,并且引用的哪层,从那层及以下此变量全部发生改变。
a = 1 def fun_1(): a = 2 def fun_2(): global a a = 3 def fun_3(): a = 4 print(a) print(a) fun_3() print(a) print(a) fun_2() print(a) print(a) fun_1() print(a)
函数的嵌套
def f1(): print("in f1") def f2(): print("in f2") f2() f1() ########### def f1(): def f2(): def f3(): print("in f3") print("in f2") f3() print("in f1") f2() f1() 函数的嵌套定义
六,函数名的本质。
函数名本质上就是函数的内存地址
1 可以被引用
def func(): print('in func') f = func print(f)
2可以被当作容器类型的元素
def func1(): pass def func2(): pass lst = [func1, func2] for el in lst: el()
3 函数名可以当做函数的参数
def func(): print("吃了么") def func2(fn): print("我是func2") fn() print("我是func2") func2(func)
4 函数名可以当做函数的返回值
def func_1(): print("这里是函数1") def func_2(): print("这里是函数2") print("这里是函数1") return func_2 fn = func_1() fn()
七,闭包
内部函数包含对外部作用域而非全剧作用域变量的引用,该内部函数称为闭包函数
#函数内部定义的函数称为内部函数
由于有了作用域的关系,我们就不能拿到函数内部的变量和函数了。如果我们就是想拿怎么办呢?返回呀!
我们都知道函数内的变量我们要想在函数外部用,可以直接返回这个变量,那么如果我们想在函数外部调用函数内部的函数呢?
是不是直接就把这个函数的名字返回就好了?
这才是闭包函数最常用的用法
def func(): name = 'eva' def inner(): print(name) return inner f = func() f()
判断闭包函数的方法__closure__
def func(): a = 10 def inner(): print(a) print(inner.__closure__) # 如果打印的是None. 不是闭包. 如果不是None, 就是闭包 func()