PYTHON进阶
闭包
- 在嵌套函数的前提下,内部函数使用了外部函数的变量,并且外部函数返回了内部函数,这个使用外部函数变量的内部函数称为闭包
- 优点:
- 无需定义全局变量即可实现通过函数,持续的访问、修改某个值
- 闭包使用的变量的作用域在函数内,难以被错误的调用修改
- 缺点:
- 由于内部函数持续引用外部函数的值,所以会导致这一部分内存空间不被释放,一直占用内存
# 例
def outer(logo):
def inner(msg):
print(f"<{logo}>{msg}<{logo}>")
return inner
fn1 = outer("A")
fn1("B")
# 结果:<A>B<A>
修改外部函数变量的值
- 需要使用nonlocal关键字修饰外部函数的变量才可在内部函数中修改它
# 例
def outer(num1):
def inner(num2):
nonlocal num1
num1 +=num2
print(num1)
return inner
fn1 = outer(10)
fn1(20)
# 结果:30
装饰器
- 装饰器其实也是一种闭包,其功能就是在不破坏目标函数原有的代码和功能的前提下,为目标函数增加新功能
def outer(func):
def inner():
print("function调用前")
func()
print("function调用后")
return inner
- 装饰器的语法糖写法
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 StrTools:
pass
str_tool=StrTool()
# --------------------------------------------------------------------------
from test import str_tool
s1 = str_tool
s2 = str_tool
print(s1)
print(s2)
# s1 s2指向一个地址
工厂模式
- 从原生的使用类的构造取创建对象的形式迁移到,基于工厂提供的方法去创建对象的形式
- 优点:
- 大批量创建对象的时候有统一的入口,易于代码维护
- 当发生修改,仅修改工厂类的创建方法即可
class Person:
pass
class Worker(Person):
pass
class Student(Person):
pass
class Teacher(Person):
pass
class Factory:
def get_person(self,p_type):
if p_type = 'w':
return Worker()
elif p_type = 's':
return Student()
else:
return Teacher()
factory = Factory()
worker = factory().get_person('w')
student = factory().get_person('s')
teacher = factory().get_person('t')
多线程
- 进程:就是一个程序,运行在系统上
- 线程:线程是归属于进程的,一个进程可以开启多个线程,执行不同的工作,是进程的实际工作最小单位
- 进程之间是内存隔离的,即不同的进程拥有各自的内存空间;线程之间是内存共享的
- 并行执行:指同一时间做不同的工作
- 进程之间就是并行执行的
- 线程也可以并行执行
threading模块
- PYTHON多线程可以通过threading模块来实现
import threading
thread_obj = threading.Thread(group= ,target= ,name= ,args= ,kwargs= )
# group:暂时不用,未来功能的预留参数
# target:执行的目标任务名
# name:线程名,一般不设置
# args:以元组的方式给执行任务传参
# kwargs:以字典方式给执行任务传参
# 启动线程,让线程开始工作
thread_obj.start()
import time
import threading
def sing():
while True:
print("SING~")
time.sleep(1)
def dance():
while True:
print("DANCE~")
time.sleep(1)
t1 = threading.Thread(target=sing)
t2 = threading.Thread(target=dance)
t1.start()
t2.start()
网络编程
Socket
- socket(简称:套接字)是进程之间通信的一个工具
- socket负责进程之间的网络数据传输
- 两个进程之间通过socket进行相互通讯,就必须有服务器和客户端
- socket服务端:等待其他进程的连接,可接收发来的信息,可以回复消息
- socket客户端:主动连接服务端,可以发送消息,可以接收消息
socket服务端
import socket
# 创建socket对象
socket_server=socket.socket()
# 绑定socket_server到指定IP和地址
socket_server.bind(('localhost',8888))
# 服务端开始监听端口
socket_server.listen(__backlog=5) # backlog为int整数,表示允许的连接数量,超出会等待,不填会自动设置一个合理值
# 接收客户端连接,获得连接对象
conn,address = socket_server.accept()
# accept是阻塞方法,没有连接会卡在当前行不向下执行代码
# accept返回的是一个二元元组(链接对象,客户端地址信息),可以使用上述形式,用两个变量接收二元元组的2个元素
print(f"接收到了客户端信息,客户端信息是:{address}")
# 客户端连接后,通过recv方法,接收客户端发送的信息
data = conn.recv(1024).decode("UTF-8")
# recv接收的参数是缓冲区大小,一般给1024即可
# recv方法的返回值是一个字节数组也就是byte对象,不是字符串,可以通过decode方法通过UTF-8编码转换为字符串对象
print(f"客户端消息:{data}")
# 通过conn(客户端当次连接对象),调用send方法可以回复信息
msg = input("请输入回复消息:").encode("UTF-8") # encode可以将字符串编码为字节数组对象
conn.send(msg)
# conn(客户端当次连接对象)和socket_server对象调用close方法,关闭连接
conn.close()
socket_server.close()
- 下载网络调试助手作为客户端测试
- [下载地址](Releases · nicedayzhu/netAssist (github.com))
- 打开exe
- 协议类型设置为TCP Client
socket客户端
import socket
# 创建socket对象
socket_client = socket.socket()
# 连接到服务端
socket_client.connect(('localhost',8888))
while True:
# 发送消息
msg = input("请输入要发送的消息:")
socket_client.send(msg.encode("UTF-8"))
if msg == 'exit':
break
# 接收返回消息
recv_data = socket_client.recv(1024).decode("UTF-8")
if recv_data == 'exit':
break
print(f"服务器回复的消息:{recv_data}")
# 关闭链接
socket_client.close()
正则表达式
- PYTHON正则表达式,使用re模块,并基于re模块中三个基础方法来做正则匹配
- 有match、search、findall三个基础方法
基础匹配
-
re.match(匹配规则,被匹配字符串)
- 从被匹配字符串开头进行匹配,匹配成功返回匹配对象(包含匹配的信息);匹配不成功返回空
-
re.search(匹配规则,被匹配字符串)
- 搜索整个字符串,找出匹配的,找到第一个就停止;找不到返回空
-
re.findall(匹配规则,被匹配字符串)
- 匹配整个字符串,找出全部匹配项;找不到返回空list:[]
元字符匹配
*正则表达式中的空格有意义
- 单字符匹配:
字符 | 功能 |
---|---|
. | 匹配任意1个字符(除了\n),\.匹配点本身 |
[] | 匹配[]中列举的字符 |
\d | 匹配数字,即0-9 |
\D | 匹配非数字 |
\s | 匹配空白,即空格、tab键 |
\S | 匹配非空白 |
\w | 匹配单词字符,即a-z,A-Z,0-9,_ |
\W | 匹配非单词字符 |
# 例
import re
s = "itheima1 @@python2 !!666 ##ticast3"
# 找出全部数字
a = re.findall(r'\d',s)
# 字符串的r标记,表示当前字符串是原始字符串,即内部的转义字符无效而是普通字符
# 找出特殊字符
a = re.findall(r'\W',s)
# 找出全部英文字母
a = re.findall(r'[a-zA-Z]',s)
print(a)
- 数量匹配:
字符 | 功能 |
---|---|
* | 匹配前一个规则的字符出现0至无数次 |
+ | 匹配前一个规则的字符出现1至无数次 |
? | 匹配前一个规则的字符出现0次或1次 |
匹配前一个规则的字符出现m次 | |
匹配前一个规则的字符出现最少m次 | |
匹配前一个规则的字符出现m到n次 |
- 边界匹配:
字符 | 功能 |
---|---|
^ | 匹配字符串开头 |
$ | 匹配字符串结尾 |
\b | 匹配一个单词的边界 |
\B | 匹配非单词边界 |
- 分组匹配:
字符 | 功能 |
---|---|
| | 匹配左右任意一个表达式 |
() | 将括号中字符作为一个分组 |