# 全局作用域(全局变量) ==》在全局作用域中访问全局变量,也可以在局部作用域中访问
import time
num1 = 10
def func():
# 局部作用域(局部变量)==》在局部作用域中访问局部变量,但是在全局作用域中无法访问
num2 = 20
# ① 在局部访问局部变量
print(num2)
# ① 在全局访问全局变量
print(num1)
# 调用函数
func()
print('----------------------------------')
# 闭包三步走
# 1 有嵌套
def outer():
b = 20
def inner():
# 2.有引用,内部函数引用了外部函数的局部变量
print(b)
# 3.有返回,内部函数的名称==》内存地址返回
return inner
# 调用outer函数
f = outer()
f() # 调用inner函数,返回outer函数中的局部变量b
print('------------------------------------')
'''
闭包的变量修改
'''
b = 50
# 1 有嵌套
def outer():
b = 20
def inner():
# 2.有引用,内部函数引用了外部函数的局部变量
# global b
# nonlocal关键字 用于嵌套环境,适用于在嵌套内部修改外部变量
nonlocal b
b = 30
print(b)
# 3.有返回,内部函数的名称==》内存地址返回
print(f'outer中的b:{b}')
inner()
print(f'inner执行后outer中的{b}')
# 调用outer函数
outer()
print(b)
print('-------------------------------')
def func():
result = 0
def inner(num):
nonlocal result
result += num
print(result)
return inner
f = func()
f(1)
f(2)
f(3)
print('-------------------------------')
# 装饰器
def check(fn):
def inner():
# 开发登录功能
print('登录功能')
# 调用原函数
fn()
return inner
# 评论功能(前提:登录)
@check # 装饰器
def comment():
print('评论功能')
# comment = check(comment) #调用check装饰器,然后把comment函数的内存地址赋值给check的fn参数
comment() # 由于comment指向了inner函数,所有commen()代表执行inner函数
print('--------------------------')
# 下载功能(前提:登录)
@check
def download():
print('下载功能')
# download = check(download)
download()
print('----------------------')
# 定义一个装饰器
def get_time(fn):
# fn局部变量
def inner():
# 给fn添加额外功能
start = time.time()
fn()
stop = time.time()
print(stop - start)
return inner
# 原函数
@get_time
def func1():
list1 = []
for i in range(100000):
list1.append(i)
# 调用函数
func1()
print('----------------------------')
# 编写通用装饰器:用于给每个函数增加日志输出功能
def logging(fn):
def inner(n1,n2):
print('输出日志:正在计算加法运算')
fn(n1,n2)
return inner
# 原有函数
@logging
def sum_num(n1, n2):
# print('输出日志:正在计算加法运算')
print(n1 + n2)
# 调用方式
sum_num(10, 20) # 相当于执行inner(10,20)
print('-----------------------------------')
# 通用装饰器,使用*args **kwargs,可以接收任意长度参数
# 编写通用装饰器:用于给每个函数增加日志输出功能
def logging(fn):
def inner(*args,**kwargs):
print('输出日志:正在计算加法运算')
fn(*args,**kwargs)
return inner
# 原有函数
@logging
def sum_num(n1, n2):
# print('输出日志:正在计算加法运算')
print(n1 + n2)
# 调用方式
sum_num(10, 20) # 相当于执行inner(10,20)
print('---------------------------------')
def logging2(fn):
def inner(*args, **kwargs):
# 添加装饰器代码(输出日志信息)
print('-- 日志信息:正在努力计算机 --')
# 执行要修饰的函数
fn(*args, **kwargs) # sum_num(a, b)
return inner
@logging2
def sum_num(*args, **kwargs):
result = 0
# *args代表不定长元组参数,args = (10, 20)
for i in args:
result += i
# **kwargs代表不定长字典参数, kwargs = {a:30, b:40}
for i in kwargs.values():
result += i
print(result)
# sum_num带4个参数,而且类型不同,10和20以元组形式传递,a=30,b=40以字典形式传递
sum_num(10, 20, a=30, b=40)
print('------------------------------')
#装饰器修饰带有返回值的参数
def logging3(fn):
def inner(*args,**kwargs):
print('------输出日志----')
# fn(*args,**kwargs)
# return None 由于inner没有返回值 所有也要加terurn
return fn(*args,**kwargs)
return inner
@logging3
def func3(n1,n2):
result = n1+n2
return result
print(func3(1,2))
# 通用装饰器编写
def logging4(fn):
def inner(*args,**kwargs):
print('------输出日志----')
return fn(*args,**kwargs)
return inner
@logging4
def sum_number(n1,n2):
return n1-n2
@logging4
def sub_number(n1,n2):
return n1+n2
print(sum_number(10,20))
print(sub_number(10,20))
print('++++++++++++++++++++++++')
# 高级装饰器,实现装饰器传参数
def logging(flag):
# flag = + 或 flag = -
def decorator(fn):
def inner(*args, **kwargs):
if flag == '+':
print('-- 日志信息:正在努力进行加法运算 --')
elif flag == '-':
print('-- 日志信息:正在努力进行减法运算 --')
return fn(*args, **kwargs)
return inner
return decorator
@logging('+')
def sum_num(a, b):
result = a + b
return result
@logging('-')
def sub_num(a, b):
result = a - b
return result
print(sum_num(10, 20))
print(sub_num(100, 80))
# 类装饰器
class Check():
def __init__(self, fn):
# fn就是要修饰函数的名称,当Check装饰器类被调用时,系统会自动把comment函数名称传递给fn变量
self.__fn = fn
# __call__方法:把一个类转换为函数的形式进行调用
def __call__(self, *args, **kwargs):
# 编写装饰器代码
print('请先登录')
# 调用comment函数本身
self.__fn(*args, **kwargs)
# 编写一个函数,用于实现评论功能,底层comment = Check(comment)
@Check
def comment():
print('评论功能')
# 调用comment函数,实现评论功能
comment()
424python装饰器
最新推荐文章于 2024-09-27 10:11:28 发布