主题
面向对象、闭包、装饰器
一、面向对象 - super关键字
python
# super(更适合单继承的场景)
# 语法:super(类型,实例对象)
# 作用:找到当前类的下一级(父类)mro继承关系
# super一般不会在类外部使用,在类内部使用时,可以不传递参数(找的是父类)1. 类的属性和方法的继承
python
class A():
name = 'zs'
def fn():
print('fn')
class B(A):
pass
直接继承了A的name和fn2. 类的动态属性和动态方法的继承
python
# 1.Father(需要继承的类).init
# 2.super.init
class A():
def __init__(self):
self.name = 'zs'
self.age = 18
a = A()
a会拥有name和age属性
class B(A):
def __init__(self):
# 继承的属性
A.__init__(self)
# 自己再添加额外的属性
self.money = 1000003. 混合继承
混合继承 = 类的属性/方法 + 动态属性/方法
4. 内置装饰器
类的方法默认叫做构造方法 - def fn(self):
@staticmethod:给类的方法进行装饰,将类的方法改造为静态方法 - def fn():
python
# 如果类里面没有使用self,改造成@staticmethod
# 单例模式使用类的属性(方法),使用类名.属性(方法名) @classmethod:给类的方法进行装饰,将类的方法改造为类方法 - def fn(cls):
python
# 装饰的方法,第一个参数是cls,cls表示类本身
# 装饰的方法一般给静态类(单例)使用二、垃圾回收机制
- 标记清除法:如果一个变量不可访达,那么这个变量对应的内存就可以被回收
- 引用计数法
- 分代回收
三、闭包
- 闭包核心:绕过垃圾回收机制的一种高级编程思想
- 闭包三要素:
- 外部函数函数嵌套内部函数(有嵌套)
- 函数内部引用外部函数的变量(有引用) 关键字nonlocal
- 返回内部函数名(不能有括号)(有返回)
python
# 使用闭包实现累计计数
def outer_fn():
count = 0
# 有嵌套
def inner_fn():
# 有引用
nonlocal count
count += 1
print(f'当前的count为{count}')
# 有返回
return inner_fn
# 接受返回值
fn = outer_fn()
# 调用
fn()四、装饰器的实现
1.有嵌套
2.有引用
3.有返回(返回的东西叫闭包)
4.有实现内容
五、装饰器的分类
1. 无参无返回值
python
import time
# 定义统计用时装饰器
def check_time(fn):
# 有嵌套
def inner_fn():
# 函数执行前时间
start = time.time()
# 有调用(外部函数形参)
fn()
# 函数执行后时间
end = time.time()
# 打印执行时间按
print('函数执行时间:%f' % (end - start))
# 返回内部函数名
return inner_fn
# 手搓
def work():
a = 1
b = 2
print(a + b)
time.sleep(2)
1.通过check装饰work,构造一个新的fn
new_work = check_time(work)
2.新的fn调用才能实现效果
new_work()
# 语法糖
@check_time
def work():
a = 1
b = 2
print(a + b)
time.sleep(2)
# 调用
work()2. 有参无返回值
核心:有参数的时候,只需要用inner_fn接收这个参数就行
python
import time
# 定义统计用时装饰器
def check_time(fn):
# 有嵌套
def inner_fn(a, b):
# 函数执行前时间
start = time.time()
# 有调用(外部函数形参)
fn(a, b)
# 函数执行后时间
end = time.time()
# 打印执行时间按
print('函数执行时间:%f' % (end - start))
# 返回内部函数名
return inner_fn
# 手搓
def work(a, b):
print(a + b)
time.sleep(2)
new_work = check_time(work)
# 调用
new_work(1, 2)
# 语法糖
@check_time
def work(a, b):
print(a + b)
time.sleep(2)
# 调用
work(1, 2)3. 无参有返回值
核心:inner_fn里面加return
python
import time
# 定义统计用时装饰器
def check_time(fn):
# 有嵌套
def inner_fn():
# 函数执行前时间
start = time.time()
# 有调用(外部函数形参)
res = fn()
# 函数执行后时间
end = time.time()
# 打印执行时间按
print('函数执行时间:%f' % (end - start))
return res
# 返回内部函数名
return inner_fn
# 手搓
def work():
a = 1
b = 2
time.sleep(2)
return (a + b)
new_work = check_time(work)
# 调用
print(new_work())
# 语法糖
@check_time
def work():
a = 1
b = 2
time.sleep(2)
return a + b
# 调用
print(work())4.有参有返回值
python
import time
# 定义统计用时装饰器
def check_time(fn):
# 有嵌套
def inner_fn(a, b):
# 函数执行前时间
start = time.time()
# 有调用(外部函数形参)
res = fn(a, b)
# 函数执行后时间
end = time.time()
# 打印执行时间按
print('函数执行时间:%f' % (end - start))
return res
# 返回内部函数名
return inner_fn
# 手搓
def work(a, b):
time.sleep(2)
return a + b
new_work = check_time(work)
# 调用
print(new_work(1,2))
# 语法糖
@check_time
def work(a, b):
time.sleep(2)
return a + b
# 调用
print(work(1, 2))5. 通用装饰器
python
# 通用装饰器模板
def check_time(fn):
# 有嵌套
def inner_fn(*args, **kwargs):
# -------------------------装饰器功能【先执行装饰器功能】
print('功能')
# -------------------------装饰器功能【先执行装饰器功能】
# 有调用(外部函数形参)
res = fn(*args, **kwargs)
# -------------------------装饰器功能【后执行装饰器功能】
print('功能')
# -------------------------装饰器功能【后执行装饰器功能】
return res
# 返回内部函数名
return inner_fn
@check_time
def work(*args, **kwargs):
num_sum = 0
# 求元组args的和
for i in args:
num_sum += i
# 求字典kwargs的和
for i in kwargs:
num_sum += kwargs[i]
print(f'和为{num_sum}')
# 补充:
# 原则:关键字不定长写在位置不定长后面
# 原则:位置参数写在默认值参数前面六、装饰器的其他使用
1. 多装饰器的使用
效果:装饰器执行顺序按照从上往下逐个执行
原理:装饰的顺序从下到上,把装饰器加函数当作一个新函数
python
# 登录
def login(fn):
def inner_fn(*args, **kwargs):
print('请先登录')
res = fn(*args, **kwargs)
return res
return inner_fn
# 评论
def comment(fn):
def inner_fn(*args, **kwargs):
print('发布评论')
res = fn(*args, **kwargs)
return res
return inner_fn
# 点赞
@login
@comment
def like():
print('点赞')2. 装饰器的参数
装饰器如果有参数,需要在原来的装饰器的基础上再包裹一层进行接收
python
def flag(flag):
def param_calc(fn):
def inner_fn(*arg, **kwargs):
res = fn(*arg, **kwargs)
if flag == '+':
print('装饰器加法执行完成~')
else:
print('装饰器减法执行完成~')
return res
return inner_fn
return param_calc
@flag('+')
def calc1(a, b):
print(a + b)
@flag('-')
def calc2(a, b):
print(a - b)
# 调用
calc1(1, 2)
calc2(1, 2)