当前位置: 首页 > news >正文

python基础day06

1.内置模块OS:

  • 简介:Python内置的与操作系统文件相关的模块,该模块中语句的执行结果通常与操作系统有关,即有些函数的运行效果在Windows操作系统和MacOS系统中不一样。
  • 常用函数:
函数名称描述说明
getcwd()获取当前的工作路径
listdir(path)获取path路径下的文件和目录信息,如果没有指定path则获取当前路径下的文件和目录信息
mkdir(path)在指定路径下创建目录(文件夹),如果要创建的文件夹存在,程序会报错FileExitsError
makedirs(path)创建多级目录
rmdir(path)删除path下的空目录,如果要删除的目录不存在,程序报错FileNotFoundError
removedirs(path)删除多级目录
chdir(path)把path设置为当前目录
walk(path)遍历目录树,结果为元组,包含所有路径名、所有目录列表和文件列表
remove(path)删除path指定的文件,如果要删除的目录不存在,程序报错FileNotFoundError
rename(old,new)将old重命名为new
stat(path)获取path指定的文件信息
startfile(path)启动path指定的文件
  • os.path模块:

        简介:是os模块的子模块,也提供了一些目录或文件的操作函数。

        常用函数:

函数名称描述说明
abspath(path)获取目录或文件的绝对路径
exists(path)判断目录或文件在磁盘上是否存在,结果为bool类型,如果目录或文件在磁盘上存在,结果为True,否则为False
join(path,name)将目录与目录名或文件名进行拼接,相当于字符串的“+”操作
splitext()分别获取文件名和后缀名,结果是元组类型(文件名,后缀名)
basename(path)从path中提取文件名
dirname(path)从path中提取路径(不包含文件名)
isdir(path)判断path是否是有效路径
isfile(path)判断file是否是有效文件

2.网络编程与通信协议:

  • 通信协议:接入网络所要遵守的“规则”,目前全球通用的通信协议即Internet协议。
  • 七层协议与四层协议:

  • IP协议:IP协议是整个TCP/IP协议族的核心, IP地址就是互联网上计算机的唯一标识。目前的IP地址有两种表示方式,即IPv4和IPv6。在命令行下使用ipconfig命令可以查看本机的IP地址。
  • TCP协议:TCP(Transmission Control Protocol)协议即传输控制协议,是建立在IP协议基础之上的。TCP协议负责两台计算机之间建立可靠连接,保证数据包按顺序发送到。它是一种可靠的、一对一的、面向有连接的通信协议。
  • TCP/IP协议中的四个层次:

  • TCP/IP协议数据发送和数据接收:

  • TCP协议的三次握手:

  • UDP协议:UDP协议又被称为用户数据包协议(User DatagramProtocol),它是面向无连接的协议,只要知道对方的IP地址和端口,就可以直接发送数据包,由于是面向无连接的,所以无法保证数据一定会到达接收方。
  • 端口号:区分计算机中的运行的应用程序的整数。端口号的取值范围是0到65535,一共65536个,其中80这个端口号分配给了HTTP服务,21这个端口号分配给了FTP服务。
  • TCP协议与UDP协议的区别:
TCP协议UDP协议
连接方面面向连接的面向无连接
连接方面传输消息可靠、不丢失、按顺序到达无法保证不丢包
传输效率方面传输效率相对较低传输效率高
连接对象数量方面只能是点对点、一对一支持一对一、一对多、多
对多的交互通信

3.Socket:

  • Socket通信模拟图:

  • Socket对象的常用方法:
方法名称功能描述
bind((ip,port))绑定IP地址和端口
listen(N)开始TCP监听,N表示操作系统挂起的最大连接数量,取值范围1-5之间,一般设置为5
accept()被动接收TCP客户端连接,阻塞式
connect((ip,port))主动初始化TCP服务器连接
recv(size)接收TCP数据,返回值为字符串类型,size表示要接收的最大数据量
send(str)发送TCP数据,返回值是要发送的字节数量
sendall(str)完整发送TCP数据,将str中的数据发送到连接的套接字,返回之前尝试发送所有数据,如果成功为None,失败抛出异常
recvfrom()接收UDP数据,返回值为一个元组(data,address),data表示接收的数据,address表示发送数据的套接字地址
sendto(data,(ip,port))发送UDP数据,返回值是发送的字节数
close()关闭套接字

4.TCP通信:

  • TCP服务器端流程如下:

       (1)使用socket类创建一个套接字对象。

       (2)使用bind((ip,port))方法绑定IP地址和端口号。

       (3)使用listen()方法开始TCP监听。
       (4)使用accept()方法等待客户端的连接。

       (5)使用recv()/send()方法接收/发送数据6.使用close()关闭套接字。

from socket import socket,AF_INET,SOCK_STREAM
# AF_INET 用于internet之间的进程通信
# SOCK_STREAM表示的是TCP协议编程# (1)创建socket对象
server_socket=socket(AF_INET,SOCK_STREAM)# (2)绑定IP地址和端口
ip='127.0.0.1'
port=8888
server_socket.bind((ip,port))# (3)使用listen()开始监听(5表示最大连接数量)
server_socket.listen(5)# (4)等待客户端的连接
client_socket,client_addr=server_socket.accept()# (5)接收来自客户端的数据
data=client_socket.recv(1024)
print("客户端发送过来的数据为:",data.decode("utf-8"))# (6)关闭socket
server_socket.close()
  • TCP客户端的流程如下:

       (1)使用socket类创建一个套接字对象。

       (2)使用connect((host,port))设置连接的主机IP和主机设置的端口号。

       (3)使用recv()/send()方法接收/发送数据。
       (4)使用close()关闭套接字。

import socket
# (1)创建socket对象
client_socket = socket.socket()# (2)IP地址和主机端口,向服务端发送连接请求
ip='127.0.0.1'
port=8888
client_socket.connect((ip,port))# (3)发送数据
client_socket.send("Welcome to python world".encode('utf-8'))# (4)关闭
client_socket.close()
  • 客户端与服务器端双向通信示意图:

  • 服务端与客户端多次通信代码示例:

       服务端代码:

import socket
# (1)创建socket对象
socket_server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)# (2)绑定IP地址和端口号
socket_server.bind(("127.0.0.1",8888))# (3)设置最大连接数量
socket_server.listen(5)# (4)等待客户连接
client_sock,client_addr=socket_server.accept()# (5)接收来自客服端的数据
info=client_sock.recv(1024).decode("utf-8")
while info!="bye":if info!="":print("接收到的数据是:", info)data=input("请输入要发送的数据:")                # 服务端要返回的数据client_sock.send(data.encode("utf-8"))          # 向客户端响应数据if data=="bye":breakinfo=client_sock.recv(1024).decode("utf-8")# (6)关闭socket
socket_server.close()
client_sock.close()

   客户端代码:

import socket
# (1)创建socket对象
client_socket = socket.socket()# (2)主机的IP和端口号
client_socket.connect(('127.0.0.1',8888))# (3)客户端先发送数据
info=""
while info!="bye":# 准备要发送的数据send_data=input("请输入客户端要发送的数据:")client_socket.send(send_data.encode("utf-8"))if send_data=="bye":breakinfo=client_socket.recv(1024).decode("utf-8")print("收到服务器响应的数据:",info)# (4)关闭socket对象
client_socket.close()

5.UDP通信:

  • 客户端与服务端通信代码示例:

      服务端代码:

from socket import socket,AF_INET,SOCK_DGRAM
# (1)创建socket对象
recv_socket=socket(AF_INET,SOCK_DGRAM)# (2)绑定IP地址和端口
recv_socket.bind(('127.0.0.1',8888))# (3)接收来自发送方的数据
recv_data,addr=recv_socket.recvfrom(1024)
print("接收到的数据为:",recv_data.decode("utf-8"))# (4)准备回复对方的数据
data=input("请输入要回复的数据:")# (5)回复
recv_socket.sendto(data.encode("utf-8"),addr)# (6)关闭
recv_socket.close()

   客户端代码:

from socket import socket, AF_INET, SOCK_DGRAM
# (1)创建socket对象
send_socket=socket(AF_INET, SOCK_DGRAM)# (2)准备发送的数据
data=input("请输入要发送的数据:")# (3)指定接收方的IP地址和端口
ip_port=("127.0.0.1",8888)# (4)发送数据
send_socket.sendto(data.encode("utf-8"),ip_port)# 接收数据
recv_data,addr=send_socket.recvfrom(1024)
print("接收到的数据是:",recv_data.decode("utf-8"))# (5)关闭socket
send_socket.close()

6.程序与进程:

  • 程序:英文单词为Program,是指一系列有序指令的集合,使用编程语言所编写,用于实现一定的功能。
  • 进程:进程则是指启动后的程序,系统会为进程分配内存空间。
  • 创建进程的方式:

      方式一 : Process(group=None,target,name,args,kwargs)

         参数说明:
         (1) group:表示分组,实际上不使用,值默认为None即可。

         (2)target:表示子进程要执行的任务,支持函数名。
         (3)name:表示子进程的名称。
         (4)args:表示调用函数的位置参数,以元组的形式进行传递。

         (5)kwargs:表示调用函数的关键字参数,以字典的形式进行传递。

from multiprocessing import Process
import os,timedef test():print(f"我是子进程,我的PID是:{os.getpid()},我的父进程是:{os.getppid()}")time.sleep(1)lst=[]
if __name__ == '__main__':print("主进程开始执行")for i in range(5):p=Process(target=test)p.start()lst.append(p)for item in lst:item.join()     # 阻塞主进程print("主进程执行结束")

       方式二 : class 子进程(Process):
                         pass

from multiprocessing import Process
import os,time
class SubProcess(Process):def __init__(self,name):super().__init__()self.name=namedef run(self):print(f"子进程名称:{self.name},PID:{os.getpid()},父进程:{os.getppid()}")if __name__ == '__main__':print("父进程开始执行")lst=[]for i in range(6):p1=SubProcess(f"进程:{i}")p1.start()lst.append(p1)for item in lst:item.join()print("父进程执行结束")
  • Process常见的方法和属性:
方法/属性名称功能描述
name当前进程实例别名 ,默认为Process-N
pid当前进程对象的PID值
is_alive()进程是否执行完,没执行完结果为True,否则为False
join(timeout)等待结束或等待timeout秒
start()启动进程
run()如果没有指定target参数,则启动进程后,会调用父类中的
run方法
terminate()强制终止进程

7.Pool进程池:

  • 进程池的原理是:创建一个进程池,并设置进程池中最大的进程数量。假设进程池中最大的进程数为3,现在有10个任务需要执行,那么进程池一次可以执行3个任务,4次即可完成全部任务的执行。
  • 创建进程池的语法结构:进程池对象=PooI(N)
  • 进程池常用的方法:
方法名功能描述
apply _async(func,args,kwargs)使用非阻塞方式调用函数func
apply(func,args,kwargs)使用阻塞方式调用函数func
close()关闭进程池,不再接收新任务
terminate()不管任务是否完成,立即终止
join0阻塞主进程,必须在terminate()或close()之后使用
  • 非阻塞方式:
from multiprocessing import Pool
import os,time
def task(name):print(f"子进程PID:{os.getpid()},执行的任务:{name}")time.sleep(1)if __name__ == '__main__':start=time.time()print("主进程开始执行")p=Pool(3)for i in range(10):p.apply_async(func=task,args=(i,))p.close()   # 关闭主进程不再接收新任务p.join()    # 阻塞父进程,等待所有子任务执行完毕后,才会执行父进程中的代码print("所有子进程执行完毕,主进程执行结束")print(time.time()-start)                 # 5.294420003890991  每次执行三个任务,共执行4次
  • 阻塞方式:
from multiprocessing import Pool
import os,time
def task(name):print(f"子进程PID:{os.getpid()},执行的任务:{name}")time.sleep(1)if __name__ == '__main__':start=time.time()print("主进程开始执行")p=Pool(3)for i in range(10):p.apply(func=task,args=(i,))p.close()   # 关闭主进程不再接收新任务p.join()    # 阻塞父进程,等待所有子任务执行完毕后,才会执行父进程中的代码print("所有子进程执行完毕,主进程执行结束")print(time.time()-start)                    # 11.40873122215271   每次执行一个任务,共执行10次
  • 并发和并行:

       并发:是指两个或多个事件同一时间间隔发生,多个任务被交替轮换着执行

       并行:是指两个或多个事件在同一时刻发生,多个任务在同一时刻在多个处理器上同时执行

8.队列:

  • 队列:进程之间可以通过队列(Queue)进行通信,队列是一种先进先出(FirstIn First Out)的数据结构。
  • 创建队列的语法结构:队列对象=Queue(N)
  • 队列常用方法:
方法名称功能描述
qsize()获取当前队列包含的消息数量
empty()判断队列是否为空,为空结果为True,否则为False
full()判断队列是否满了,满结果为True,否则为False
get(block=True)获取队列中的一条消息,然后从队列中移除,block默认值为True
get_nowait()相当于get(block=False),消息队列为空时,抛出异常
put(item,block=True)将item消息放入队列,block默认为True
put_nowait(item)相当于put(item,block=False),消息队列为满时,抛出异常
  • 代码示例:
from multiprocessing import Queue
if __name__ == '__main__':q=Queue(3)          # 创建队列q.put("hello")      # 将hello放入队列q.put("python")     # 将python放入队列q.put("world")      # 将world放入队列q.get()             # 将hello从队列中移除if not q.empty():for i in range(q.qsize()):print(q.get())     # python  world
  • q.put(item,block=True,timeout=2) 

       put中的第三个参数单位是秒,表示等待n秒后,队列没有空位置就抛出异常

 from multiprocessing import Queueif __name__ == '__main__':q = Queue(3)q.put("hello")q.put("world")q.put("python")q.put("java",block=True,timeout=2)   # 等待2秒,队列没有空位置就抛出异常

9.线程:

  • 线程:线程是CPU可调度的最小单位,被包含在进程中,是进程中实际的运作单位。一个进程中可以拥有N多个线程并发执行,而每个线程并行执行不同的任务。

  • 创建线程:

      方式一 : 函数式创建线程:t=Thread(group,target,name,args,kwargs)

         参数说明:
                   (1)group:创建线程对象的进程组
                   (2)target:创建的线程对象所要执行的目标函数
                   (3)name:创建线程对象的名称,默认为“Thread-n”
                   (4)args:用无组以位置参数的形式传入target对应函数的参数

                   (5)kwargs:用字典以关键字参数的形式传入target对应函数的参数

       方式二 : 使用Thread子类创建线程

                    (1)自定义类继承threading模块下的Thread类
                    (2)实现run方法

# 函数式创建线程
import threading
from threading import  Thread
import time
def test():for i in range(3):time.sleep(1)print(f"线程:{threading.current_thread().name}正在执行{i}")
if __name__ == '__main__':start = time.time()print("主线程开始执行")lst=[Thread(target=test) for i in range(2)]for item in lst:item.start()for item in lst:item.join()print(f"一共耗时:{time.time()-start}秒")# 使用类创建线程
import threading
from threading import Thread
import time
class SubThread(Thread):def run(self):for i in range(3):time.sleep(1)print(f"线程:{threading.current_thread().name}正在执行{i}")
if __name__ == '__main__':start = time.time()print("主线程开始执行")lst=[SubThread() for i in range(2)]for item in lst:item.start()for item in lst:item.join()print("主线程执行完毕")
  • 线程操作共享数据的安全性问题:

由于多个线程之间是并发执行,每个线程中的多个任务是并行执行的,就会导致不同线程中的任务会操作同一个全局变量,造成共享数据的安全性问题,因此需要使用Lock对共享数据进行锁定和解锁。

# 售票案例
from threading import Thread,Lock
import threading
import time
lock_obj = Lock()
ticket=50
def sale_ticket():global ticketfor i in range(100):     # 每个排队窗口假设有100人lock_obj.acquire()   # 上锁if ticket > 0:print(f"{threading.current_thread().name}正在出售第{ticket}张票")ticket -= 1time.sleep(1)lock_obj.release()  # 释放锁if __name__ == '__main__':for i in range(3):          # 创建三个线程,代表三个窗口t = Thread(target=sale_ticket)t.start()

10.生产者与消费者模式

生产者与消费者模式:是线程模型中的经典问题,与编程语言无关。当程序中出现了明确的两类任务,一个任务负责生产数据,一个任务负责处理生产的数据时就可以使用该模式。

  • Python内置模块queue由的Queue类:
方法名称功能描述
put(item)向队列中放置数据,如果队列为满,则阻塞
get()从队列中取走数据,如果队列为空,则阻塞
join()如果队列不为空,则等待队列变为空
task_done()消费者从队列中取走一项数据,当队列变为空时,唤醒调用join()的线程

相关文章:

  • 云防火墙(安全组)配置指南:从入门到精通端口开放 (2025)
  • 基于 HTTP 的单向流式通信协议SSE详解
  • AI语音助手的Python实现
  • 【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
  • SE(Secure Element)加密芯片与MCU协同工作的典型流程
  • R语言速释制剂QBD解决方案之三
  • vue3 报错Missing semicolon
  • 【C++】std::bind和std::placeholders
  • 盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
  • 【Java】Ajax 技术详解
  • 基于当前项目通过npm包形式暴露公共组件
  • 检查项目中的依赖是否有更新——npm outdated
  • 基于SpringBoot实现的汽车资讯网站设计与实现【源码+文档】
  • 【ubutnu 24.04 】 nomachine 安装
  • 第21节 Node.js 多进程
  • 安宝特案例丨又一落地,Vuzix AR眼镜助力亚马逊英国仓库智能化升级!
  • rm视觉学习1-自瞄部分
  • Latex vscode安装、配置与使用-Windows
  • Spring是如何解决Bean的循环依赖:三级缓存机制
  • 比较数据迁移后MySQL数据库和达梦数据库中的表
  • 设计微信小程序/网站优化排名金苹果系统
  • 代客做网站/网络推广和网络销售的区别
  • 沈阳网站备案照相/产品推广介绍怎么写
  • 网站怎么做外链接地址/万江专业网站快速排名
  • 学校网站建设自查报告/足球比赛统计数据
  • 江苏平台网站建设价位/广州网站建设推广专家