1、闭包
一个双层嵌套函数,内层函数可以访问外层函数的变量,将内层函数作为外层函数的返回,此内层函数就是闭包函数
优势:不定义全局变量,也可以让函数持续访问和修改一个外部变量;可以避免闭包函数引用的外部变量被误修改
缺点:额外内存占用
nonlocal关键字的作用:
在闭包函数想要修改外部函数的变量值,可以利用nonlocal声明这个外部变量。
##闭包
#优势:1)内部函数可以依赖外部变量;2)外部变量是外部函数的临时变量;
#3)双重嵌套实现了:外部变量可以持续的记录数据,同时确保了外部变量不是全局的,不易被篡改,
#缺点:由于内部函数持续引用外部函数值,所以会导致这一部分内存一只不得释放,占用内存
def outer(lope):
def inner(msg):
print(f"<{lope}<>{msg}<{lope}>")
return inner
##内部函数inner被称为一个闭包函数,它的其中一个变量来自外部函数,
##函数调用时,可以保证内外函数均正常运行。
#1、打破了内部函数调用外部变量的限制,内部函数调用多次,外部变量依旧有效
#调用示例
fn1 = outer("黑马程序员")
fn1("大家好")
fn1("大家好")
#2、内部函数可以修改外部变量
def outer(lope):
def inner(msg):
nonlocal lope
lope+= msg
print(lope)
return inner
#调用示例
fn = outer(10)
fn(10)
fn(10)
fn(10)
##用闭包实现ATM机制存取小案例
def count(num=0):
def atm(num2, deposite = True):
nonlocal num
if deposite:
num += num2
print(f"存款{num2},账户余额:{num}")
else:
num -= num2
print(f"取款{num2},账户余额:{num}")
return atm
#调用示例
atm = count()
atm(100)
atm(200)
2、装饰器:闭包的一种
功能:在不破坏目标函数原有代码和功能的前提下,为目标函数增加新功能
1、构建闭包
2、@闭包
3、调用原来的函数
#源代码
def sleep():
import time
import random
print("睡眠中")
time.sleep(random.randint(1,5))
#传统调用
print("我要睡觉了")
sleep()
print("我睡醒了")
#装饰器
#写法1
def outer(func):
def inner():
print("我要睡觉了")
func()
print("我睡醒了")
return inner
def sleep():
import time
import random
print("睡眠中")
time.sleep(random.randint(1,5))
#调用
fn = outer(sleep)
fn()
#写法2
def outer(func):
def inner():
print("我要睡觉了")
func()
print("我睡醒了")
return inner
@(outer)
def sleep():
import time
import random
print("睡眠中")
time.sleep(random.randint(1,5))
#调用
sleep()
3、设计模式(下面只介绍单例模式和工厂模式)
3.1 单例设计模式
单例模式就是对一个类,只获取其唯一的类实例对象,持续复用它。
特点:1、节省内存;2、节省创建对象的开销
定义:保证一个类只有一个实例,并提供一个访问它的全局访问点
适用场景:当一个类只能有一个实例,而客户可以从一个总所周知的访问点访问它时。
##常规调用
class strto:
pass #假设该类存储在syr_tool.py文件中
#调用
s1 = strto
s2 = strto
##上面对应两个示例
##单例模式
#某些场景下,我们希望针对同一实例进行操作,可以调用单例模式
#调用
from str_tools import strto
s1 = strto
s2 = strto
3.2 工厂机制
定义:当需要大量一个类的实例的时候,使用工厂机制。
优势:1、大批量创建对象的时候有同一的入口,易于代码维护;
2、当发生修改,进修改工厂类的创建方法即可;
3、面向对象编程
#工厂机制
class student:
pass
class techer:
pass
class worker:
pass
class PersonFactory:
def get_person(self, p_type):
if p_type == 'w':
return worker()
elif p_type == 's':
return student()
else:
return teacher()
pf = PersonFactory()
worker = pf.get_person("w")
student = pf.get_person("s")
teacher = pf.get_person("t")
4、多线程操作
进程:在操作系统上运行的一个程序,就成为一个运行进程
线程:同一进程,可以开启若干线程,执行不同的工作
多进程:操作系统中的多任务运行
注意点:
1、进程之间的内存是隔离的。
2、线程之间的内存是共享的。
并行执行:同一时间做不同工作
4.1、多线程编程
4.1.1 threading模块
#单线程执行任务
import time
def sing():
while True:
print("sing a song")
time.sleep(1)
def dance():
while True:
print("dance dance")
time.sleep(1)
if __name__ == '__main__':
sing()
dance()
##结果会显示,一直在唱歌,跳舞循环未执行--->单线程的缘故
##改善:多线程通信
import time
impirt threading
def sing():
while True:
print("sing a song")
time.sleep(1)
def dance():
while True:
print("dance dance")
time.sleep(1)
if __name__ == '__main__':
sing_thread = threading.Thread(target=sing)
dance_thread = threading.Thread(target=dance)
sing_thread.start()
dance_thread.start()
4.1.2 给任务传参
#args:以元组方式传参(-,-)
#kwargs: 以字典形式传参{"-": -}
import time
impirt threading
def sing():
while True:
print(msg)
time.sleep(1)
def dance():
while True:
print(msg)
time.sleep(1)
if __name__ == '__main__':
sing_thread = threading.Thread(target=sing, args=("sing a song", ))
dance_thread = threading.Thread(target=dance, kwargs={"msg": "dance dance"})
sing_thread.start()
dance_thread.start()
5、网络编程
5.1、服务端编程
#通过socket进行服务端开发
import socket
#创建socket对象
socket_server = socket.socket()
#绑定IP地址
socket_server.bind(localhost",888)
#监听
docket_server.listen(1)
#listen中传递的参数,表示接收的连接数量
#等待连接
#result = socket_server.accept()
#cons = result[0]#客服端和服务器的连接对象
#address = result[1]#客户端地址信息
conn,address = result_server.accept()
#accept是一个阻塞方法,如果没建立连接,会停留在当前行
print(f"接收到了客户端的连接,客户端信息是:{address}")
data: str = conn.recv{1024}.decord("UTF-8")
#recv接收的参数是缓冲区大小,一般是1024
#recv发送的是一个字节数据信息,也就是bytes对象,可以decode成UTF-8模式,将字节数据转化成字符串对象
print(f"客户端发来的信息是,{data}")
#发送回复信息
msg = input(" ".encode("UYTF-8"))
conn.send(msg)
#关闭连接
conn.close()
socket_server.close()
#持续通信
while True:
data: str = conn.recv{1024}.decord("UTF-8")
#recv接收的参数是缓冲区大小,一般是1024
#recv发送的是一个字节数据信息,也就是bytes对象,可以decode成UTF-8模式,将字节数据转化成字
#符串对象
print(f"客户端发来的信息是,{data}")
if msg == 'exit':
break
#发送回复信息
msg = input("输入要和客户端回复的消息:")
conn.send(msg.encode("UTF-8"))
#关闭连接
conn.close()
socket_server.close()
5.2、客户端通信开发
#客户端
import socket
#创建socket
socker_client = cosket.socket()
#连接服务器r
socket_client.connect(("localhost",8888))
while True:
#发送信息
msg = input("请输入要给服务器发送到消息:")
if msg == 'exit':
break
socket_client.send("msg".encode("UTF-8"))
#接收信息
recv_data = socket_client.recv(1024)
print(f"服务器回复的消息是:,{recv_data.decode('UTF-8')}")
#关闭连接
socket_client.close()