文章目录
函数的返回值
Python函数的返回值可以通过使用return关键字来指定。当调用该函数时,会将函数中所有被return语句后面跟着的表达式作为结果返回。
return 自定义函数的返回值
概念:return 把函数内部的数据返回到函数的外面,返回到函数的调用处
1.return + 六大标准数据类型 , 除此之外还可以 返回函数 或者 是类对象
2.return 在执行时,意味着终止函数,后面的代码不执行.
3.如果不定义return返回值,默认返回None
(1) return + 六大标准数据类型,每次只能返回一个数据
def func(): # return 111 # return 6.89 # return "你好帅啊,我爱死你乐" # return [1,2,3] #如果要返回多个值,将数据放入列表或元祖中,返回个列表或元祖 # return {"a":1,"b":2} return 1,2,3 # 返回元组 res = func() print(res)
运行运行
(2) return 在执行时,意味着终止函数,后面的代码不执行.
def func(): print(1) print(2) return 3 print(4) res = func() print(res)
运行运行
后面的4没打印出来
def func():
for i in range(5):
if i == 3:
return 4
print(i)
res = func()
print(res)
i = 3的时候,返回4,后面的循环就没在执行
(3) 如果不定义return返回值,默认返回None
def func():
pass
res = func()
print(res) # None
#注意点 打印的数据和返回的数据不是等价的,返回的数据是可以自定义的;
res = print(1234) print(res) # None
运行运行
没定义返回值,返回None
案例 模拟±*/计算器
"""
功能: 完成计算
参数: 2个数字和运算符
返回值: 计算后的结果
"""
def calc(num1,num2,sign):
if sign == "+":
return num1 + num2
elif sign == "-":
return num1 - num2
elif sign == "*":
return num1 * num2
elif sign == "/":
if num2 == 0:
return "除数不能为零"
return num1 / num2
else:
return "抱歉,超出了我的运算范围."
res = calc(3,5,“+”)
res = calc(3,5,“-”)
res = calc(3,5,“*”)
res = calc(3,0,“/”)
res = calc(3,0,“&”)
print(res)
写函数谨记从三个方面去抓:功能,参数,返回值。这三个方面搞好了,就能写出优秀的函数
函数的变量
####全局变量和局部变量
“”"
1.概念
局部变量:在函数内部定义的变量就是局部变量
全局变量:在函数外部定义的变量 或者在函数内部使用global关键字声明是全局变量
2.作用域:
局部变量的作用范围仅仅在函数的内部,在函数外部无法调用,强制调用报错
全局变量的作用范围横跨整个文件
#作用域:作用范围
#命名空间 : 划分一块区域保存所有数据,以字典的方式存储(变量与值形成映射关系).一共三种.
(1)内建命名空间:解释器启动时创建,直到解释器运行结束,生存周期最长
(2)全局命名空间:文件运行时创建,直到解释器运行结束,生存周期较长
(3)局部命名空间:函数调用时,里面的局部变量才创建,调用结束后即释放,生存周期较短
#命名空间的提出是为了划分和控制变量是否可见,以及生存周期的长短.
#命名空间 创建顺序:(了解)
python解释器启动->创建内建命名空间->创建全局命名空间->创建局部命名空间
#命名空间 销毁顺序:(了解)
函数调用结束后->销毁函数对应的局部命名空间数据->销毁全局命名空间数据->销毁内建命名空间数据
内置的函数,关键字,属性等放到内置命名空间
全局变量 与 局部变量 及 其关键字的使用
#局部变量:函数内部的变量是局部变量,作用域仅在函数内部可见(局部命名空间)
#全局变量:函数外部的变量是全局变量,作用域横跨整个文件(全局命名空间)
#内置函数:内建命名空间
– globals() :返回字典,存放着全局作用域所有内容
– locals() :返回字典,当前作用域所有内容(locals调用之前的变量)
– global :关键字:声明全局变量获修改全局变量
– nonlocal :关键字:修改局部变量(当前函数上一层的局部变量)
LEGB原则(即就近原则找变量)
#找寻变量的调用顺序采用LEGB原则(即就近原则)
B —— Builtin(Python);Python内置模块的命名空间 (内建作用域)
G —— Global(module); 函数外部所在的命名空间 (全局作用域)
E —— Enclosing function locals;外部嵌套函数的作用域 (嵌套作用域)
L —— Local(function);当前函数内的作用域 (局部作用域)
依据就近原则,从下往上 从里向外 依次寻找
3.生命周期:该变量的作用时长
内置命名空间 -> 全局命名空间 -> 局部命名空间 (开辟空间顺序)
内置属性 > 全局属性 > 局部属性 (作用时长:长->短)
“”"
1 局部变量
def func():
# 定义一个局部变量
a = 1
# 获取当前的局部变量
print(a)
# 修改一个局部变量
a = 2
print(a)
func()
# print(a) error
局部变量在函数外部调用报错
2.全局变量
# 定义一个全局变量
b = 10
# 获取当前的全局变量
print(b)
# 修改一个全局变量
b = 20
print(b)
def func():
print(b)
func()
全局变量,函数内部外部都能调用
3.函数内部定义全局变量
在函数内部要想定义全局变量,使用global关键字
def func(): global c c =30 func() print(c)
运行运行
4.函数内部修改全局变量
需要先用global关键字修饰
d = 50 def func(): global d d = 51 func() print(d)
运行运行
总结:global的使用
如果当前不存在全局变量,可以在函数内部通过global关键字来定义全局变量
如果当前存在全局变量,可以在函数内部通过global关键字来修改全局变量
函数名的使用
python中的函数可以像变量一样,动态创建,销毁,当参数传递,作为值返回,叫第一类对象.其他语言功能有限
def func(): print( "我是func函数")
运行运行
(1)动态创建
a = 1
print(a)
a = func
a()
如下,通过函数名赋值的方式,相当于创建了与func功能一样的a函数
(2)动态销毁
del a
#a()
#func()
(3)当参数传递
def func2():
return "我是func2函数"
def func1(f):
return f() # “我是func2函数”
res = func1(func2)
print(res)
(4)作为值返回
def func3():
print( "我是func3函数" )
def func4(f):
return f
res = func4(func3)
print(res)
res()
print(“<===>”)
返回的是个函数名,函数对象,再调用,打印出func1()函数的输出
(5)函数名可以作为容器类型数据的元素
lst = [func,func3]
for i in lst:
i()
print(“<=========>”)
变量可以怎么用,函数就可以怎么用
__doc__ 或者help查看文档。可以给自定义的函数写说明文档,告诉别人怎么更方便的使用,__doc__可以帮我们获取到函数内部自定义的文档
一般是三个引号包裹着的注释,__doc__只能查看到三个引号注释的部分
help查看的更全面,包含函数名和以及定义的参数
def big_chang_cishen(something):
"""
功能: 教你怎么吃大肠
参数: 吃的内容
返回值: 是否满意
"""
print("把{}洗一洗".format(something))
print("直接找肠子头,放嘴里,吸一下")
print("擦擦嘴,满意的放下肠子头")
return "吃完了,真好吃~"
big_chang_cishen(“生肠子”)
# 方法一
res = big_chang_cishen.doc
print(res)
# 方法二
help(big_chang_cishen)
函数的嵌套
互相嵌套的两个函数:
包裹在外层的叫做外函数,内层的就是内函数
def outer(): # inner() def inner(): print("我是inner函数")
运行运行
在外层调用外层函数,如果外层函数没有打印,内层函数有打印,不执行内层函数的打印
在内部调用内部函数,才能打印
#(1)内部函数可以直接在函数外部调用么 不行
#inner()
#(2)调用外部函数后,内部函数可以在函数外部调用吗 不行
#outer()
#inner()
#(3)内部函数可以在函数内部调用吗 可以
outer()
#(4)内部函数在函数内部调用时,是否有先后顺序 有的
#先定义在调用
#在其他语言中有预加载的机制,提前把函数驻留到内存中,然后再去编译脚本内容
#python没有预加载函数的机制,只能先定义在调用;
#外函数是outer 中间函数是inner 最里层是smaller ,调用smaller函数
def outer(): def inner(): def smaller(): print("我是smaller函数") smaller() inner() outer()
运行运行
#多层函数调用,只能层层都调用,才能显示出最内层函数内容,不能断层
以下调用才是正常的
LEGB 原则
def outer():
<span class="token keyword">def</span> <span class="token function">inner</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">smaller</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">print</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span> smaller<span class="token punctuation">(</span><span class="token punctuation">)</span> inner<span class="token punctuation">(</span><span class="token punctuation">)</span>
outer()
LEGB原则(就近找变量原则)
#找寻变量的调用顺序采用LEGB原则(即就近原则)
B —— Builtin(Python);Python内置模块的命名空间 (内建作用域)
G —— Global(module); 函数外部所在的命名空间 (全局作用域)
E —— Enclosing function locals;外部嵌套函数的作用域(嵌套作用域)
L —— Local(function);当前函数内的作用域 (局部作用域)
依据就近原则,从下往上 从里向外 依次寻找
即便id未定义,但它是内置函数,在最内层也能调用
nonlocal的使用 (用来修改局部变量)
nonlocal遵循LEGB原则 nonlocal 只能修改局部变量
(1) 它会找当前空间上一层的变量进行修改
(2) 如果上一层空间没有,继续向上寻找
(3) 如果最后找不到,直接报错
(1)它会找当前空间上一层的变量进行修改
def outer(): a = 10 def inner(): nonlocal a a = 20 print(a) inner() print(a) outer()
运行运行
(2)如果上一层空间没有,继续向上寻找
def outer(): a = 20 def inner(): a = 15 def smaller(): nonlocal a a = 30 print(a) smaller() print(a) inner() print(a) outer()
运行运行
#如果有多层定义同一变量,nonloacl找到最近一层的变量,即不再向上寻找,只修改最近一层的变量
(3)如果最后找不到,直接报错
nonlocal 只能修改局部变量,不能修改全局变量
a = 20
def outer():
def inner():
def smaller():
nonlocal a
a = 30
print(a)
smaller()
print(a)
inner()
print(a)
outer()
error
如果在L,E层未找到该变量的定义,会直接报错
(4) 不通过nonlocal 是否可以修改局部变量呢?
def outer(): lst = [1,2,3] def inner(): lst[-1] = 3000 inner() print(lst) outer()
运行运行
#使用nonlocal,如果多层都有这个变量的定义,只可以修改最近层变量的值
针对可变类型数据也一样,只修改最近层变量的值
不使用nonlocal,当变量是不可变类型,只能修改本层内的变量
不使用nonlocal,当变量是可变类型,可以直接修改各层数据
在使用nonlocal的层,不能再定义该变量