python笔记
1.数据类型
2.整形 int
3.浮点型 float
4.布尔 bool:true false
5.字符串str,用单引号表示
6.列表:list,有序的可变序列,可以存储任意类型的元素,用方括号 [] 表示
list1 = [1,2,3,4]
支持索引、切片、添加、删除等操作。
列表是可变的(Mutable)
7.元组:tuple,有序的不可变序列,用圆括号 () 表示
tuple1=(1,2,3,4)
元组是不可变的(Immutable),适合存储不希望被修改的数据。
8.字典:dict,键值对(Key-Value)的无序集合,用花括号 {} 表示。
dict1={‘a’:1,’b’:2}
键必须是不可变类型(如字符串、数字、元组),值可以是任意类型。
字典是可变的。
9.集合:set,无序且不重复的元素集合,用花括号 {} 表示。
set1 = {1,2,3,4}
集合支持交集、并集、差集等操作。
集合是可变的,但元素必须是不可变类型(如数字、字符串、元组)。
10.None 类型,表示空值或无值,通常用于初始化变量或表示函数无返回值。
x = None
11.字节类型(Bytes),表示二进制数据,用 b'' 表示。
data = b"Hello"
# 将字节对象转换为列表
print(list(data)) # 输出: [72, 101, 108, 108, 111]
# 遍历字节对象
for byte in data:
print(byte) # 输出: 72, 101, 108, 108, 111
12.字节数组(Bytearray),类似于字节类型,但是可变的。
byte_array = bytearray(b"Hello")
13.范围类型(Range),表示一个不可变的数字序列,通常用于循环。
my_range = range(0, 10) # 生成 0 到 9 的数字
14.自定义类型,Python 支持通过类(Class)定义自定义数据类型
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
p = Person("Alice", 25)
标识符:程序员自己定义,有特殊功能的字符组合
1.只能由字母数字,下划线组成
2.不能以数字开头
3.不能使用关键字
4.严格区分大小写
Python 中的主要数据类型包括:
数字类型:int, float, complex
布尔类型:bool
字符串类型:str
序列类型:list, tuple, range
集合类型:set, frozenset
映射类型:dict
二进制类型:bytes, bytearray
空值类型:None
占位符
常用格式符:
%s:字符串
%d:整数
%f:浮点数
%x:十六进制数
str.format() 方法,使用 {} 作为占位符,通过 format() 方法填充内容。
name = "Bob"
age = 30
print("Name: {}, Age: {}".format(name, age))
name = 'Jason'
age = 18
gender = 'male'
print('name=%s,age=%d,gender=%s' % (name,age,gender))
print('name={},age={},gender={}'.format(name,age,gender))
精度问题
pi = 3.1415926535
print("Pi: %.2f" % pi) # 保留 2 位小数
数据类型转化:
price=input('请输入苹果的价格(元/斤):')
weight=input('输入购买的重量(斤):')
money = float(price)*float(weight)
print('总价:%.2f'%money)
算数运算符
面向对象
class Car:
def run(self):
print('running')
Self关键字,用于指向对象实例本身
在类的内部调用方法,用Self.方法名()
class Car:
def run(self):
print(f'running:{self}')
def work(self):
self.run()
def show(self):
print(f'color:{self.color}, speed:{self.speed}')
pass
# 创建对象
mayCar = Car()
mayCar.color = 'red'
mayCar.speed = 120
mayCar.show()
魔法方法
__init__ :在创建对象时自动调用,用于初始化对象属性。__init__ 方法不应该有返回值(确切地说,它的返回值必须是 None)
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
p = Person("Alice", 25)
__str__ 和 __repr__ 字符串表示
__str__:用于返回对象的用户友好字符串表示(str() 和 print() 时调用)
__repr__:用于返回对象的正式字符串表示(调试和开发时使用)
__del__ 是一个魔法方法(Magic Method),用于定义对象被销毁时的行为。它被称为析构方法(Destructor Method),当对象的引用计数降为 0 或被垃圾回收器(Garbage Collector)回收时,Python 会自动调用 __del__ 方法。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"{self.name} ({self.age} years old)"
def __repr__(self):
return f"Person('{self.name}', {self.age})"
def __del__(self):
print('----del----')
pass
if __name__ == '__main__':
p = Person('Jason',18)
print(p)
pass
if __name__ == '__main__': 是 Python 中一个非常重要的惯用写法,它的作用可以用以下要点清晰解释:
1. 核心作用
判断当前模块是直接被运行,还是被导入为模块:
如果是直接运行,__name__ 的值是 '__main__',代码块会执行。
如果是被其他文件导入,__name__ 的值是模块名(文件名),代码块不会执行。
继承:
多继承的顺序:如果继承了多个父类,优先调用第一个父类的属性和方法
私有属性和方法:
只能在类的内部使用,不能在类的外部使用,如果想在类的外部使用只能通过公共方法
多态(Polymorphism)
1. 多态的核心思想
三个条件:继承,函数重写,父类引用指向子类对象
同一个接口:对不同类型对象使用相同的操作(如方法调用、运算符等)。
不同表现:对象会根据自身类型自动选择正确的实现方式
(1) 继承 + 方法重写(经典多态)
class Animal:
def speak(self):
raise NotImplementedError("子类必须实现此方法")
class Dog(Animal):
def speak(self):
return "汪汪!"
class Cat(Animal):
def speak(self):
return "喵喵~"
def animal_talk(animal: Animal):
print(animal.speak())
# 同一函数处理不同子类对象
animal_talk(Dog()) # 输出: 汪汪!
animal_talk(Cat()) # 输出: 喵喵~
(2) 鸭子类型(Duck Typing)
Python 的特色多态方式:不强制要求继承关系,只要对象有对应方法即可
class Car:
def run(self):
print("汽车行驶中...")
class Plane:
def run(self):
print("飞机飞行中...")
def move(obj):
obj.run() # 只要对象有 run() 方法即可
move(Car()) # 输出: 汽车行驶中...
move(Plane()) # 输出: 飞机飞行中...
5. 与其他语言的对比
特性PythonJava/C++
实现方式鸭子类型 + 继承继承 + 接口
类型检查运行时动态检查编译时静态检查
灵活性高(无需显式继承)低(需声明类型)
总结
Python 的多态:主要通过鸭子类型和继承实现,强调"行为"而非"类型"。
关键原则:"如果它走起来像鸭子,叫起来像鸭子,那么它就是鸭子"。
实践建议:
优先使用鸭子类型减少耦合
需要严格规范时用抽象基类
运算符重载要符合直觉
抽象类,抽象接口 @abstractmethod
1. 抽象类(Abstract Class)
特点:
定义:包含至少一个抽象方法(未实现的方法)的类,不能直接实例化。
目的:强制子类实现特定的方法,确保统一的接口。
实现方式:使用 abc 模块(Abstract Base Class)。
2. 抽象接口(Abstract Interface)
特点:
定义:纯抽象的类(只有方法声明,没有实现),用于严格定义行为契约。
目的:完全分离"做什么"(接口)和"怎么做"(实现)。
Python 实现:由于 Python 没有原生接口,通常用抽象类模拟。
from abc import ABC, abstractmethod
class Flyable(ABC): # 模拟接口
@abstractmethod
def fly(self):
pass
class Bird(Flyable):
def fly(self):
print("用翅膀飞")
class Airplane(Flyable):
def fly(self):
print("用引擎飞")
def start_flying(obj: Flyable):
obj.fly()
start_flying(Bird()) # 输出: 用翅膀飞
start_flying(Airplane()) # 输出: 用引擎飞
关键点:
接口中所有方法都是抽象的(无具体实现)。
一个类可以实现多个接口(多继承)。
3. 类方法 (@classmethod)
特点:
必须接收 cls 参数:指向当前类对象(不是实例)。
可操作类状态:能修改类属性,常用于工厂模式。
继承友好:子类调用时,cls 自动指向子类。
cls 是类方法(@classmethod)的第一个参数,代表当前类对象本身(不是实例对象)。它的作用类似于实例方法中的 self,但指向的是类而非实例。
class Pizza:
default_topping = "cheese"
def __init__(self, topping=None):
self.topping = topping or self.default_topping
@classmethod
def set_default_topping(cls, topping):
cls.default_topping = topping # 修改类属性
@classmethod
def margherita(cls):
return cls("mozzarella") # 使用 cls 创建实例
# 修改类属性
Pizza.set_default_topping("pepperoni")
p1 = Pizza()
print(p1.topping) # 输出: pepperoni
# 工厂方法创建实例
p2 = Pizza.margherita()
print(p2.topping) # 输出: mozzarella
2. 静态方法 (@staticmethod)
特点:
无隐式参数:不需要 self 或 cls。
独立性:类似于普通函数,只是放在类中便于组织代码。
使用场景:与类相关但不依赖类或实例状态的工具函数。
类名.静态方法名
如何选择?
使用场景推荐方法
需要操作类属性或创建实例@classmethod
独立工具函数,无需访问类状态@staticmethod
需要支持继承多态@classmethod
学生管理系统
程序入口:显示操作界面
1.添加学员
2.修改学员
3.删除学员
4.查询某个学员
5.显示所有学员
6.保存学员
0.退出系统
学生类:姓名,学号,年龄,性别,电话
管理类:增删改查
启动类:
浅拷贝 与 深拷贝
浅拷贝只拷贝了第一层数据并开辟存储空间,修改第一层数据源数据不会改变,修改第二层数据源数据会改变
深拷贝拷贝所有数据并开辟对应的存储空间,修改所有数据源数据都不会改变
闭包
是指一个函数(称为嵌套函数)引用了其外部作用域(enclosing scope)中的变量,即使外部函数已经执行完毕,这些变量仍然会被保留在内存中。
def outer_func(x): # 外层函数
def inner_func(y): # 内层函数(闭包)
return x + y # 引用了外层函数的变量 x
return inner_func # 返回内层函数(但不调用)
# 创建闭包
closure = outer_func(10) # x=10 被 inner_func 记住
print(closure(5)) # 输出 15(10 + 5)
print(closure(20)) # 输出 30(10 + 20)
案例
def outter(a,b):
def inner(x):
return a*x+b
return inner
# 5x + 1
close = outter(5,1)
# x = 2
result = close(2)
print(result)
nonlocal关键字的作用
主要作用
允许嵌套函数修改外层函数中的变量:当你在一个嵌套函数内部需要修改外层函数(但不是全局作用域)中的变量时,使用nonlocal。
明确标识变量的作用域来源:清楚地表明该变量来自外层作用域,而不是当前函数的局部变量。
def outer():
x = 10
def inner():
nonlocal x # 声明x来自外层作用域
x = 20 # 现在可以修改外层函数中的x
inner()
print(x) # 输出20,因为inner()修改了x
outer()
装饰器的作用
功能扩展:在不改变原函数代码的情况下,为函数添加额外的功能(如日志记录、性能测试、权限校验等)
代码复用:将多个函数共有的功能抽取出来,避免重复代码
代码解耦:将核心业务逻辑与辅助功能分离,使代码更清晰
AOP编程:实现面向切面编程(Aspect-Oriented Programming)的思想
装饰器的生成条件:
1.有嵌套
2.有引用
3.又返回
4.有额外功能
def comment():
print('登录')
def outter(func):
def inner():
print('注册')
func()
return inner
dec = outter(comment)
dec()
语法糖
@装饰器名
def regist(func):
def inner():
print('注册')
func()
return inner
@regist
def comment():
print('登录')
comment()
通用装饰器:参数是不定长的,有返回值
def dec(add):
def inner(*a,**b):
return add(*a,**b)
return inner
@dec
def add(*a,**b):
sum = 0
for i in a:
sum = sum + i
for i in b:
sum = sum + i
return sum
print(add(1,1))
多个装饰器装饰一个函数:从上到下执行
def enterPSD(func):
def inner():
print('plase enter PSD')
func()
return inner
def enterCode(func):
def inner():
print('plase enter code')
func()
return inner
@enterPSD
@enterCode
def logging():
print('logging')
logging()
带参数的装饰器:
def log(flag):
def dec(func):
def inner(a,b):
if flag == '+':
print('adding')
if flag == '-':
print('subbing')
func(a,b)
return inner
return dec
@log('+')
def add(a,b):
return a+b
@log('-')
def sub(a,b):
return a-b
add(1,2)
sub(1,2)
网络编程
三要素:ip 端口 协议
socket
基本概念
通信端点:Socket是网络通信的端点,包含IP地址和端口号
双向通道:提供全双工的通信通道,可以同时发送和接收数据
协议支持:支持TCP(可靠连接)和UDP(无连接)等协议
服务器端:
创建socket
绑定IP和端口(bind)
监听连接(listen)
接受连接(accept)
收发数据(recv/send)
关闭连接
客户端:
创建socket
连接服务器(connect)
收发数据(send/recv)
关闭连接
一个服务器对应多个客户端
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('127.0.0.1', 12345))
server_socket.listen(1)
print("等待客户端连接...")
while True:
client_socket, addr = server_socket.accept()
print(f"连接来自: {addr}")
data = client_socket.recv(1024)
print(f"收到数据: {data.decode()}")
client_socket.send(b"Hello, Client!")
client_socket.close()
server_socket.close()
多进程
import multiprocessing
import os
import time
def coding(self):
for i in range(10):
print(f'----coding:{i}----')
time.sleep(0.1)
pass
def listening(self):
for i in range(10):
print(f'----listening:{i}----')
time.sleep(0.1)
pass
if __name__ == '__main__':
processes = []
worker = [coding,listening]
for i in range(2):
p = multiprocessing.Process(target=worker[i], args=(i,))
processes.append(p)
p.start()
for p in processes:
p.join() # 等待所有进程结束
p.join() 是一个非常重要的方法调用,它的主要作用是阻塞当前进程,直到目标进程 p 执行完毕。这里的 p 是一个 multiprocessing.Process 对象
进程之间不共享全局变量
子进程被创建一次主进程就要执行一次
多进程中daemon=True的含义
与普通进程的区别
特性守护进程(daemon=True)普通进程(daemon=False)
主进程退出时自动终止继续运行
能否创建子进程不能能
是否需要join()通常不需要通常需要
清理工作不保证执行正常执行
线程
1. 定义
进程:进程是程序的一次执行实例,是操作系统资源分配的基本单位(如内存、文件句柄、CPU时间等)。每个进程拥有独立的地址空间,互相隔离。
线程:线程是进程内的一个执行单元,是CPU调度的基本单位。一个进程可以包含多个线程,所有线程共享进程的资源(如内存、文件等)。
线程是无序的
主线程会等待所有子线程执行完之后再执行
线程之间共享全局变量
如何解决线程之间的安全问题: 线程锁lock = threading.Lock(),加锁lock.acquire(),释放锁 lock.release(),注意死锁问题
import threading
x = 0
# 创建一把锁
lock = threading.Lock()
def add1():
lock.acquire()
for i in range(1000000):
global x
x += 1
lock.release()
print(f"x1 = {x}")
def add2():
lock.acquire()
for i in range(1000000):
global x
x += 1
lock.release()
print(f"x2 = {x}")
if __name__ == '__main__':
# 创建线程
t1 = threading.Thread(target=add1)
t2 = threading.Thread(target=add2)
# 启动线程
t1.start()
t2.start()
# 等待线程结束
t1.join()
t2.join()
print(f"x = {x}")
with语法
with 语句是 Python 中用于资源管理的关键语法,它简化了 try-finally 模式,确保资源(如文件、锁、数据库连接等)在使用后能被正确释放。
1. 基本语法
with expression [as variable]:
# 代码块
2. 工作原理
with 语句背后的机制是上下文管理器协议,要求对象实现两个方法:
__enter__(): 进入上下文时调用,返回值赋给 as 后的变量
__exit__(): 退出上下文时调用,处理清理工作
# 传统方式
f = open('file.txt', 'r')
try:
data = f.read()
finally:
f.close()
# 使用with(推荐)
with open('file.txt', 'r') as f:
data = f.read()
# 文件会自动关闭,即使发生异常
优势总结
自动资源管理:确保资源被正确释放
代码简洁:减少try-finally样板代码
异常安全:即使代码块抛出异常,资源也会被释放
可读性强:明确显示资源的作用域
with语句是Python中"资源获取即初始化"(RAII)模式的实现,是编写健壮、安全代码的重要工具。
yield关键字