闭包
为什么用闭包
全局变量有被修改的风险
代码在命名空间上(变量定义)不够干净
闭包怎么用
使用nonlocal关键字修改外部函数的值
def atm(account_amount = 0):
def inner(num, deposit=True):
#使用nonlocal关键字修改外部函数的值
nonlocal account_amount
if deposit:
account_amount += num
print(f"存款:+{num}, 账户余额:{account_amount}")
else:
account_amount -= num
print(f"存款:-{num}, 账户余额:{account_amount}")
return inner
fn = atm()
fn(100)
fn(500)
fn(300,deposit=False)
装饰器
功能:也是一种闭包,就是在不破坏目标函数原有的代码和功能的前提下,为目标函数增加新功能
普通写法
#装饰器
def outer(func):
def inner():
print("我睡觉了")
func()
print("我起床了")
#返回的方法不用加括号
return inner
def sleep():
import random
import time
print("睡觉中......")
time.sleep(random.randint(1, 5))
#运行
#传入的方法不用加括号
fn = outer(sleep)
fn()
装饰器的快捷写法(语法糖)
@xxx
#装饰器
def outer(func):
def inner():
print("我睡觉了")
func()
print("我起床了")
#返回的方法不用加括号
return inner
@outer
def sleep():
import random
import time
print("睡觉中......")
time.sleep(random.randint(1, 5))
sleep()
设计模式
单例模式
是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在
-
定义:保证一个类只有一个实例,并提供一个访问它的全局访问点
-
适用场景:当一个类只能用一个实例,而客户可以从一个众所周知的访问点访问它时
class strTool: pass str_tool = strTool() """ 在别的地方导包就可以保证同一个对象 """
-
持续复用
-
节省内存
-
节省创建对象的开销
工厂模式
当需要大量创建一个类的实例的时候,可以用工厂模式
即:
从原生的使用类的构造区创建对象的形式
到
基于工厂提供的方法去创建对象的形式
使用工厂类的get_person()方法去创建具体的类对象
优点:
-
易于代码维护
-
修改只需修改工厂类的创建方法即可
-
符合现实世界的模式
class Person:
pass
class Worker(Person):
pass
class Student(Person):
pass
class Teacher(Person):
pass
class PersonFactory:
def get_person(self, p_type):
if p_type == 'w':
return Worker()
elif p_type == 's':
return Student()
else:
return Teacher()
person_factory = PersonFactory()
worker = person_factory('w')
stu = person_factory('s')
teacher = person_factory('t')
多线程
介绍
进程:一个程序运行在系统之上,等于一个公司
线程:归属于进程,一个进程可以开启多个线程,执行不同的工作,等于多个员工,进程实际的工作者
一个进程运行多个线程:多线程运行
threading模块
python的多线程可以通过threading模块来实现
thread_obj =
threading.Thread([group [, target [, name [, args [,kwargs]]]]])
- group:暂时没用,未来功能的预留参数
- target:执行的目标任务名
- args:以元组的方式给执行任务传参
- kwargs:以字典方式给执行任务传参
- name:线程名
实例:
import time
import threading
def sing(msg):
while True:
print(msg)
time.sleep(1)
def dance(msg):
while True:
print(msg)
time.sleep(1)
if __name__ == '__main__':
sing_thread = threading.Thread(target=sing,args=("我在唱歌", ))
dance_thread = threading.Thread(target=dance,kwargs={"msg" : "我在跳舞"})
#让线程开始
sing_thread.start()
dance_thread.start()
Socket
进程之间通信的一个工具
进程之间进行网络通信需要socket
服务端
"""
演示socket服务端开发
"""
import socket
#创建Socket对象
socket_server = socket.socket()
#绑定ip地址和端口
socket_server.bind(("localhost", 8888))
#监听端口
socket_server.listen(1)
#等待客户端链接
# result = socket_server.accept()
# conn = result[0] # 客户端和服务端的链接对象
# address = result[1] # 客户端的地址信息
#直接用两个变量接收二元元组的两个元素
#accept()是阻塞方法
conn, address = socket_server.accept()
#接收客户端信息
data = conn.recv(1024).decode("UTF-8")
# recv接收的参数是缓冲区大小,一般给1024
# recv返回值是字节数组,需要用decode方法通过UTF-8编码,将字节数组转换为字符串
#发送回复消息
msg = input("请输入").encode("UTF-8")# 字符串编码成字节数组
conn.send(msg)
#关闭链接
conn.close()
socket_server.close()
客户端
import socket
socket_client = socket.socket()
socket_client.connect(("localhost", 8888))
while True:
#发送消息
msg = input("请输入消息")
socket_client.send(msg.encode("UTF-8"))
#接收返回消息
recv_data = socket_client.recv(1024)
if recv_data.decode("UTF-8") == "exit":
break
else:
print(recv_data.decode("UTF-8"))
#关闭
socket_client.close()
正则表达式
基础匹配
使用re模块,基于re模块中三个基础方法
match,search,findall
-
match 从头匹配,开头不匹配就不理
-
search 搜索整个字符串,找到第一个就不继续找
-
search 搜索整个字符串,找到第一个就不继续找
import re
s = "python itheima"
#match 从头匹配,开头不匹配就不理
result = re.match("it", s)
print(result)
#search 搜索整个字符串,找到第一个就不继续找
result = re.search("py", s)
print(result)
#findall 找出全部匹配项
result = re.findall("it", s)
print(result)
元字符匹配
递归
方法自己调用自己