函数作用域和装饰器
目录
- 课件:函数的作用域和装饰器
- 知识点一:函数作用域
- 知识点二:递归
- 知识点三:闭包
- 知识点四:装饰器(重、难点)
课件:函数的作用域和装饰器
知识点一:函数作用域
知识点:global、nonlocal
思考一下:
def func():
name = 'laowang'
print(name) # 能打印吗?
func()
print(name) # 能打印吗?
为什么没有被定义
执行依然报错,还是回到刚才那句话:即使执行了一下函数,name的作用域也只是在函数内部,外部依然无法进行调用;
name = "hello"
def f1():
name = "world"
def f2():
name = "python"
print(name)
f2()
f1()
# 定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。
# 局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。
# 调用函数时,所有在函数内声明的变量名称都将被加入到作用域中
当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了。
x = 123
def func():
global x
x += 1
return x
a = func()
print(a) # 124 global 就是用来修改全局变量的
# 如果要修改嵌套作用域
def func1():
x = 123
def func2():
nonlocal x
x += 1
return x
return func2()
a = func1()
print(a) # 124 nonlocal 就是用来修改 嵌套作用域的变量的
知识点二:递归
def func()
print('') 不演示
func()
func()
# 必须要有出口 内存溢出:内存不够,通常在运行大型软件或游戏时,软件或游戏所需要的内存远远超出了你主机内安装的内存所承受大小,就叫内存溢出。此时软件或游戏就运行不了,系统会提示内存溢出,有时候会自动关闭软件,重启电脑或者软件后释放掉一部分内存又可以正常运行该软件
# 在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
# 0 1 1 2 3 5 8 13
# 递归
def fibonacci(a):
if a == 0: # 简写 if a == 0 or a == 1: 与或非 逻辑运算符
return 0
elif a == 1:
return 1
else:
return fibonacci(a-1) + fibonacci(a-2)
a = fibonacci(20)
print(a)
# 递归乘积
def factorial(num): # feik toolr ao
if num>1:
result = num*factorial(num-1)
else:
result = 1
return result
a = factorial(999) # 报错 998 不会
print(a)
知识点三:闭包
闭包是函数里面嵌套函数,外层函数返回里层函数,这种情况称之为闭包
# 闭包 内部函数调用外部函数的的变量,外函数返回内函数的引用
def func():
def func1():
return 'hello'
return func1
print(func())
加括号就是调用
def func(x):
def func1():
return 'hello'+x
return func1
print(func('world')())
# 什么是引用
# 在python中一切都是对象,包括整型数据1,函数,其实是对象。
# 当我们进行a=1的时候,实际上在内存当中有一个地方存了值1,然后用a这个变量名存了1所在内存位置的引用。
# 引用就好像c语言里的指针,大家可以把引用理解成地址。
# a只不过是一个变量名字,a里面存的是1这个数值所在的地址,就是a里面存了数值1的引用。
'''
相同的道理,当我们在python中定义一个函数def demo(): 的时候,
内存当中会开辟一些空间,存下这个函数的代码、内部的局部变量等等。这个demo只不过是一个变量名字,
它里面存了这个函数所在位置的引用而已。我们还可以进行x = demo, y = demo,
这样的操作就相当于,把demo里存的东西赋值给x和y,这样x 和y 都指向了demo函数所在的引用,
在这之后我们可以用x() 或者 y() 来调用我们自己创建的demo() ,
调用的实际上根本就是一个函数,x、y和demo三个变量名存了同一个函数的引用。
'''
def dome1():
a = 100
def dome2():
return a + a
return dome2
a = dome1()
print(a())
------------------------------------
li = []
for i in range(4):
def func():
return i
li.append(func)
for f in li:
print(f()) 3 3 3 3
------------------------------------
li = []
for i in range(4):
def func(i):
def func1():
return i
return func1
li.append(func(i))
print(li)
for f in li:
print(f()) 0 1 2 3
知识点四:装饰器(重、难点)
# 装饰器
# 闭包的应用
# 写函数
def outer():
a = 2
def inner():
print(a)
return inner# 返回来的是函数体
x = outer# 函数体
a = x()# 返回值,对象 a = inner
a()# inner()调用
概念:不改变原有函数的基础上,给函数增加一些新的功能
不会,不影响之后写代码
会,轻松很多,节省代码量
def func1(func3):
def func2():
print('----验证功能----')
func3()
return func2
def func3():
print('----登录功能----') # 登陆功能,不改变增加验证功能
a = func1(func3)
a()