1、闭包
1.1、为什么要使用闭包
一下代码是模拟ATM机器存取款的代码,咱们看下有什么问题
# 账户总余款
account_amount = 0
def atm(num, deposit=True):
"""
ATM机器
:param num: 存取款金额
:param deposit: 是否是存款,默认true
:return:
"""
global account_amount
if deposit:
account_amount += num
print(f"存款:{num},账户余额:{account_amount}")
else:
account_amount -= num
print(f"取款:{num},账户余额:{account_amount}")
if __name__ == '__main__':
# 存款
atm(300)
# 存款
atm(300)
# 取款款
atm(100, False)
总结:
通过全局变量account_amount记录账户余款,尽管功能实现没有问题,但是存在一下问题
①、代码在命名空间上不够干净(变量定义)、整洁
②、全局变量有被修改的风险
由于存在以上两个问题,我们需要使用到闭包
1.2、使用闭包
我们将1.1代码改造如下:
def account_create(init_amount=0):
def atm(num, deposit=True):
# 注意:需要使用nonlocal 关键字修饰外部函数的变量,才可以在内部函数中修改它
nonlocal init_amount
"""
ATM机器
:param num: 存取款金额
:param deposit: 是否是存款,默认true
:return:
"""
if deposit:
init_amount += num
print(f"存款:{num},账户余额:{init_amount}")
else:
init_amount -= num
print(f"取款:{num},账户余额:{init_amount}")
return atm
if __name__ == '__main__':
fn = account_create(0)
fn(300)
fn(200)
fn(100, False)
在函数嵌套的前提下,内部函数使用了外部函数的变量,并且外部函数返回了内部函数,我们把这个使用外部函数变量的内部函数称为闭包。
1.3、简单闭包
def outer(logo):
def inner(msg):
print(f"{logo}:{msg}")
return inner
if __name__ == '__main__':
fn1 = outer("张三")
fn1("大家好")
fn2 = outer("李四")
fn2("hello,大家好")
1.4、闭包的注意点
-
优点:
无需定义全局变量即可实现通过函数,持续的访问、修改某个值
闭包使用的变量的所用于在函数内,难以被错误的调用修改
-
缺点:
由于内部函数持续引用外部函数的值,所以会导致这一部分内存空间不被释放,一直占用内存
2、装饰器
装饰器其实也是一种闭包, 其功能就是在不破坏目标函数原有的代码和功能的前提下,为目标函数增加新功能。
def outer(func):
def inner():
print("我要睡觉了")
func()
print("我起床了")
return inner
"""
这里要增加 @外部的方法名
"""
@outer
def sleep():
import random
import time
print("睡眠中....")
time.sleep(random.randint(1, 3))
if __name__ == '__main__':
sleep()
3、单例模式
单例模式需要通过两个文件实现
定义test_10.py 文件,内容如下
class StrTools:
pass
str_tools = StrTools()
定义test_11.py文件,内容如下
from test_10 import str_tools
if __name__ == '__main__':
s1 = str_tools
s2 = str_tools
# 如果打印的s1和s2内存地址一致,则说明单例成功
print(s1)
print(s2)
4、工厂模式
"""
定义人类
"""
class Person:
def introduce(self):
"""
自我介绍
:return:
"""
pass
"""
定义工人,继承至Person
"""
class Worker(Person):
def introduce(self):
"""
自我介绍
:return:
"""
print("我是工人")
"""
定义学生
"""
class Student(Person):
def introduce(self):
"""
自我介绍
:return:
"""
print("我是学生")
"""
定义教师
"""
class Teacher(Person):
def introduce(self):
"""
自我介绍
:return:
"""
print("我是教师")
"""
定义工厂类
"""
class Factory:
def create_person(self, p_type) -> Person:
"""
创建人类
:param p_type: 类型
:return:
"""
if p_type == 'w':
return Worker()
elif p_type == 's':
return Student()
else:
return Teacher()
return None
if __name__ == '__main__':
f = Factory()
w = f.create_person("w")
s = f.create_person("s")
t = f.create_person("t")
w.introduce()
s.introduce()
t.introduce()
5、多线程编程
绝大多数编程语言,都允许多线程编程,Pyhton也不例外。
Python的多线程可以通过threading模块来实现。
5.1、实例
import threading
import time
def sing(arg):
"""
定义唱歌方法,无限循环
:return:
"""
while True:
print(arg)
time.sleep(1)
def dance(arg):
"""
跳舞,无限循环
:return:
"""
while True:
print(arg)
time.sleep(1)
if __name__ == '__main__':
# 注意这里,target=函数名称,不能加小括号,否则线程无效
sing_thread = threading.Thread(target=sing, args=("我在唱歌",))
dance_thread = threading.Thread(target=dance, args=("我在跳舞",))
sing_thread.start()
dance_thread.start()
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/144606.html