python新手入门笔记(十二)——垃圾回收
闭包处理
在函数内部再定义一个函数,并且这个函数用到了外部函数的变量,那么
将这个函数以及用到的这些变量,称之为闭包。
def outer(num1):
def inner(num2):
print(f'在inner函数中,num2的值是{num2}')
return num1 + num2
return inner
res = outer(10)
print(res(100))
闭包有什么作用:
可以读取函数内部的变量
让这些变量的值始终保持在内存中,不会在f1调用后被自动清除。
大白话的意思就是,我们需要一些数据存在得长一点,一些数据用完就扔,但不可能一次次把两者都重复输入,此时闭包就体现出它的作用。
nonlocal函数
nonlocal关键字修饰变量后标识该变量是上一级函数中的局部变量。
# 累加生效
def outer(x):
def inner(y):
nonlocal x
x += y
return x
return inner
res = outer(10)
print(res(1)) # 11
print(res(2)) # 13
装饰器
在原来的函数基础上增加一些功能。
遵循开放 封闭原则
装饰没有参数的函数
def check_login(func):
def inner():
print('hahaha')
return func()
return inner
@check_login
def f1():
# check_login()
print('f1')
f1()
用途很广,最典型之一是为登陆功能加上验证功能。
被装饰的函数有参数
def check_login(func):
def inner(a,b):
print(f'函数{func.__name__}运行了')
return func(a,b)
return inner
@check_login
def f1(a,b):
# check_login()
return a+b
f1(4,5)
被装饰的函数有不定长参数
def outer(func):
def inner(*args,**kwargs):
print(f'函数{func.__name__}运行了')
func(*args,**kwargs)
return inner
@outer
def foo(x,y,z):
print(x+y+z)
foo(4,5,6)
装饰器的返回值
无返回值:
from time import ctime # 捕获时间
def timefunc(func):
def wrapped():
print(f'{func.__name__}运行于{ctime()}')
func()
return wrapped
@timefunc
def foo1():
print('foo-----------------')
foo1()
有返回值:
from time import ctime # 捕获时间
def timefunc(func):
def wrapped():
print(f'{func.__name__}运行于{ctime()}')
func() # 返回None的关键点
return wrapped
@timefunc
def foo2():
return 'cccccccccccccccccccc'
print(foo2()) # 返回None
如果想返回设定内容:
from time import ctime
def timefunc(func):
def wrapped():
print(f'{func.__name__}运行于{ctime()}')
return func() # return 一个函数对上述两种情况都是用
return wrapped
@timefunc
def foo2():
return 'cccccccccccccccccccc'
print(foo2())
小结:写装饰器时,内部不要直接调用函数,而是返回
return
函数的执行结果
装饰器本身有参数
def outer_s(printRes = False):# 再加一层函数用来带参数
def outer(func):# 如果只有两层,是不能带参数的,这一层只能带被装饰的函数参数。
def inner(*args,**kwargs):
print(f'函数{func.__name__}运行了')
if printRes:
print(func(*args,**kwargs))
else:
return func(*args,**kwargs)
return inner
return outer
@outer_s(True)
def foo(s,length):
return s[:length]
foo('hello world',5)
类装饰器
用类做一个装饰器,用call方法给某个方法添加功能。
不能执行的dog()。
class Dog:
def run(self):
pass
dog = Dog()
dog.run()
dog()
能执行的dog():
class Dog:
def run(self):
pass
# 定义call方法
def __call__(self, *args, **kwargs):
print('狗对象被执行了')
dog = Dog()
dog.run()
dog()
类装饰器装饰器执行对象
class Demo:
def __init__(self,func):
# 初始化函数
# 创建对象时,会接收一个函数作为参数
self.__func = func # 设置一个私有属性,指向了传入的函数
def __call__(self, *args, **kwargs):
print('添加功能')
# 在call方法中调用传入的参数(函数)
self.__func(*args,**kwargs)
@Demo #类装饰器
def add(a,b,c):
print(a + b + c)
demo = Demo(add)
demo(5,6,7)
函数被多个装饰器装饰
执行结果遵循就近原则。
def makeBold(func):
def wrapped():
return "<b>" + func() + "<b>"
return wrapped
def makeItalic(func):
def wrapped():
return "<i>" + func() + "<i>"
return wrapped
@makeBold
@makeItalic
def set1():
return 'helloworld'
print(set1())
拓展
for…else…
for i in range(10):
print(i)
if i>3:
break
else:
print('helloworld')
# for 循环 else结构 循环中如果有break 或contiue else不执行