面向对象
类:是用于创建对象的模板,类是抽象出来的;
抽象:提取事物的属性和方法,进行归类;
对象:类的具体的实例;一切皆为对象;
编程思想:
面向过程:将问题拆分成步骤,一步一步地解决问题;
面向对象:解决复制问题时先分类,每一类问题通过面向过程解决;
面向对象的四大特性:
1.封装:将数据封装到对象的属性中,将方法封装到类中;(把数据和方法包在一起,主要体现在两方面:将同一类方法封装到了一个类中;将数据封装到了对象中,在实例化一个对象时,可以通过__init__初始化方法在对象中封装一些数据,便于以后使用。)
2.继承:子类继承父类的属性和方法,提高代码的复用性;(子类继承父类的方法和类变量(不是拷贝一份,父类的还是属于父类,子类可以继承而已))
3.多态:不同的类可以使用相同名称的方法实现不同功能;(不同的对象调用同一个接口,表现出不同的状态,称为多态,多态可以增加程序的灵活性和扩展性)
4.组合:一个子类继承多个父类的属性和方法,实现功能的组合;
实例1:
from datetime import datetime
class Goods:
def init(self, name, price, create_time = datetime(now), manufacturers, about, expiration_date):
self.name = name
self.price = price
self.create time =create_time
self.mf = manufacturers
self.about = about
self.e_ date =expiration_date
def str(self):def
return f'{self.name}-{self.price}-{self.mf}-{self.about}-{self.e_date}'
def set_price(self, price):
self.price = price
def get_expiration_date(self):
date =self.create time + timedelta(days=365)
return date.strftime('%F %T'
g = Goods('泡面',5)
print(g1)
print(g1.get_expiration_date())
g1.set_price(5.5)
print(g1)
实例2:
class Person:
class_name = 'Person' # 类属性,所有Person对象共享
count = 0 # 类属性,统计创建了多少个Person对象
# 初始化方法:创建对象时自动调用
def init(self, name, age, gender):
# 实例属性
self.name = name
self.age = age
self.gender = gender
self.__money = 0 # 私有属性,双下划线开头, 外面 不能直接访问 Person.count += 1 # 每创建一个 人 ,count 总数 加1
# 类方法1:获取总人数,利用装饰器把方法转为属性
@classmethod # 子类:派生类,继承class类
def get_count(cls):
return cls.count # 返回总人数 ,这个方法和具体对象无关,只关心Person类的情况
# 类方法2:获取类名
@classmethod
def get_class_name(cls):
return cls.class_name:
# 实例方法 - 对象能做什么 - 跑步、打招呼
def run(self):
# self就是调用这个方法的对象
print(self.name, '正在跑步。。。')
def say_hi(self):
print(f'{self.name}说:"你好!"')
# 类的实例化,创建具体的人
p1 = Person('小米', 18, '男')
print(p1.name) # 输出:小米
print(p1.name, p1.age, p1.gender) # 这是属性,不加括号, 输出:小米 18 男
p1.run() # 这是方法,可以加括号, 输出:小米 正在跑步。。。
p1.say_hi() # 输出:小米说:"你好!"
p1 = Person().init(p1, '小米', 18, '男')
p2 = Person('小红', 17, '女')
print(Person.get_class_name()) # 可以通过类直接调用,不需要创建对象
# 查看对象和类的内部信息
print(p1.dict) # 小 米 的属性字典 ,输出:{'name': '小米','age': 18,'gender': '男'} - 这就是p1的所有值
print(Person.dict) # Person类的属性字典
第一个是对象的 dict - 存储实例属性,第二个是类的 dict - 存储类的内容,访问属性时,Python会先在对象的__dict__中找,找不到再去类的__dict__中找
对象:(三要素)值、类型、id
-
值(Value) - 对象的内容
-
类型(Type) - 对象属于哪个类
-
ID(身份标识) - 对象在内存中的地址
print(type(p1)) # p1是Person类型 : <class 'main.Person'>
print(type(1)) # 1 的类型是整数 : <class 'int'>
可视化图解
内存示意图:
Person类(类型对象)
┌───────────┐
│ dict: │
│ class_name: 'Person' │
│ count: 2 │
│ init: 函数 │
│ run: 函数 │
│ say_hi: 函数 │
└───────────┘
↑ 继承
p1对象(实例对象) p2对象(实例对象)
┌───────┐ ┌────────┐
│ dict: │ │ dict: │
│ name: '小明' │ │ name: '小红' │
│ age: 18 │ │ age: 17 │
│ gender: '男' │ │ gender: '女' │
│ __money: 1000│ │ __money: 0 │
└────────┘ └───────┘
类型:Person 类型:Person
ID: 0x7f8a1b ID: 0x7f8a2c
属性:对于对象的各种描述信息,一些具体的数据;
方法:对象的行为,操作,功能;
成员(实例)属性:属于对象的属性 self.属性名
成员(实例)方法:属于对象的方法 第一个参数是self
__属性:私有属性或方法,只能在类的内部调用;
方法:魔术方法,特殊功能的方法
init:对象的初始化,类似于构造函数
del:析构函数,当对象被删除时执行
str:打印对象时执行
call:当对象被作为函数执行时执行
类属性、类方法:属于类的属性和属于类的方法;所有者是类本身,通过类和对象可以调用
静态方法:封装在类中的普通函数
总结:
面向对象进阶特性极大增强了 Python 的类设计能力:
-
@property 实现优雅的属性访问控制,替代传统 getter/setter。
-
类方法和静态方法扩展了类的功能,分别用于操作类属性和定义工具函数。
-
多重继承与 MRO 解决了复杂继承关系中的方法调用顺序问题。
-
抽象类通过 abc 模块定义接口规范,强制子类实现特定方法。
-
上下文管理器自动管理资源,确保安全释放。
-
元类控制类的创建过程,适合框架级别的灵活设计。
面向对象和面向过程的区别
区别
面向过程思维:
- "执行者"思维,适合编写小规模程序
- 我们首先思考"按照什么步骤"实现,一步一步最终完成,适合一些简单的事情,不需要协作关注"程序的逻辑流程"
面向对象思维:
- "设计者"思维,适合编写大型程序
- 更加关注"对象之间的关系"
- 我们首先思考"怎么设计这个东西",然后我们把这个东西拆分成一个个的物体object(对象),然后通过分工协作来完成,每个类完成一个部分
相同点
都是解决问题的思维方式,都是代码的组织方式
配合
宏观面向对象,微观面向过程;
简单问题还得面向过程,复杂问题,就得面向对象了,面向对象是宏观把握,从整体上分析系统
Python并发编程
并发:同一时刻有很多事情(请求)需要处理;
并行:同时执行,是处理并发的一种方式;
队列(消息队列):生产者消费者模型......
进程:运行中的程序,资源的最小管理单元;
线程:是进程中的一个最小的执行单元,一个进程中至少包含一个线程;
协程:微线程,用户态线程,非阻塞的线程;
- 多进程:同一个程序在启动多次并同时运行,进程间隔离,需要特殊方法才能共享数据;
- 案例:连锁店
- 多线程:启动多个线程执行相同或不同的功能,多线程共享进程内的全局数据;
- 案例:多个服务员
- 协程:一个线程内部的可以快速切换执行不同的任务;
- 案例:烧水时做别的家务
Python网络编程
一、网络编程基础:TCP/IP 与 Socket
网络通信的基础是 TCP/IP 协议族,其中:
-
IP 协议:负责将数据从一个主机传输到另一个主机(基于IP地址定位主机)。
-
TCP/UDP 协议:位于传输层,负责数据在主机内的进程间传输(基于端口区分进程)。
-
TCP:面向连接、可靠传输(数据不丢失、不重复、按序到达),适合文件传输、HTTP 等场景。
-
UDP:无连接、不可靠传输(速度快,不保证数据完整性),适合实时通信(如视频通话、游戏)。
Socket(套接字)是网络编程的核心接口,用于描述IP地址和端口,是进程间通信的端点。通过Socket,程序可以发送和接收网络数据。
二、TCP 编程(socket 模块)
TCP 通信需要先建立连接(三次握手),再传输数据,最后断开连接(四次挥手)。Python 的 socket 模块提供了 TCP 通信的底层实现。
1.引用socket模块
import socket
2.建立socket对象,设置网络模式
AF_INET:IPV4,SOCKSTREAM:TCP
server = socket.socket()
port = '1234'
3.绑定IP与端口
server.bind(('0.0.0.0', 1234))
print(f'服务启动,端口号为:{port}')
4.监听连接,等待被访问
server.listen(10) # 括号里加'允许等待的数量'
5.接受客户端的请求数据
client_socket, client_ip = server.accept()
print(client_socket, client_ip)
数据解码后才能读取
print(client_socket.recv(1024).decode('utf-8'))
6.给客户端返回响应数据
client_socket.sendall('收到'.encode('utf-8'))
7.断开客户端连接
client_socket.close()
server.close('服务正在关闭。。。')
# 完整版
服务器端流程:创建 Socket → 绑定 IP 和端口 → 监听连接 → 接受客户端连接 → 收发数据 → 关闭连接。
import socket
1. 创建 TCP Socket(AF_INET:IPv4,SOCK_STREAM:TCP)
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2. 绑定 IP 和端口(host 为空表示监听所有网卡,port 需 >1024 且未被占用)
server_addr = ("", 8888) # 等价于 ("0.0.0.0", 8888)
server_socket.bind(server_addr)
3. 监听连接(backlog:最大等待连接数)
server_socket.listen(5)
print("服务器启动,监听端口 8888...")
while True: # 循环接受客户端连接
4. 接受客户端连接(阻塞,直到有客户端连接)
client_socket, client_addr = server_socket.accept()
print(f"接收到来自 {client_addr} 的连接")
try:
5. 接收客户端数据(1024:一次最多接收 1024 字节)
data = client_socket.recv(1024)
if data: # 若收到数据
print(f"收到客户端消息:{data.decode('utf-8')}") # 字节转字符串
发送响应
response = "已收到:" + data.decode("utf-8")
client_socket.sendall(response.encode("utf-8")) # 字符串转字节
else:
print(f"客户端 {client_addr} 断开连接")
finally:
6. 关闭客户端连接(服务器主 socket 保持监听)
client_socket.close()
import socket
1.创建socket对象
client = socket.socket()
2.建立连接
client.connect(('127.0.0.1', 1234))
3.发送数据到服务端
client.sendall('哇塞sai'.encode('utf-8'))
4.接受服务端的数据
print(client.recv(1024).decode('utf-8'))
5.断开连接
client.close()
# 完整版
客户端流程:创建 Socket → 连接服务器 → 收发数据 → 关闭连接。
import socket
1. 创建 TCP Socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2. 连接服务器(需指定服务器 IP 和端口)
server_addr = ("127.0.0.1", 8888) # 本地测试用回环地址
client_socket.connect(server_addr)
try:
3. 发送数据
message = "Hello, TCP Server!"
client_socket.sendall(message.encode("utf-8"))
4. 接收服务器响应
data = client_socket.recv(1024)
print(f"收到服务器响应:{data.decode('utf-8')}")
finally:
5. 关闭连接
client_socket.close()