Mooreの小站

Moore的个人小站

Python 第三节

2025-03-27

一、多态

发生的前提:要有继承,子类要重写父类的方法

  • 写一个方法实现多态

class Animal:
    def say(self):
        print("动物也会说话")

class Dog(Animal):
    def say(self):
        print("汪汪汪")

class Cat(Animal):
    def say(self):
        print("喵喵喵")

def animal_say(animal):
    animal.say()

dog = Dog()
cat = Cat()

animal_say(dog) # 汪汪汪
animal_say(cat) # 喵喵喵

二、类属性和静态方法

1、类属性

(1)特点

  • 不用实例化就可以调用,直接就是类名.属性名

  • 内存就保留一份,归类所有

(2)使用

  • 声明

  • 调用

  • 修改

    • 类名.属性名 → 正确的修改

    • 对象名.属性名 → 不正确的,只修改了当前对象给他新增了一个值而已

2、静态方法

  • 直接通过类名进行调用,类名.方法名,注意不需要传self

class Dog():
    food = "骨头"  # 声明类属性

    def say(self):
        print("汪汪汪")

    @staticmethod  # 使用装饰器定义静态方法
    def test():
        print('静态方法')

print(Dog.food) # 调用类属性并输出:骨头
Dog.food = "狗粮" # 正确修改类属性
dog = Dog()
dog.food = "肉"
print(dog.food) # 单纯给这个dog对象新增一个food属性,输出:肉
dog1 = Dog()
print(dog1.food) # 类属性被修改,输出:狗粮
Dog.test() # 调用静态方法,输出:静态方法

3、类方法

  • 类方法是使用@classmethod装饰器定义的方法,其第一个参数必须是cls(代表类本身),通过cls可以直接访问或修改类属性,但不涉及实例属性。类方法支持通过类名直接调用(如ClassName.method())或通过实例调用

class Counter:
    total = 0  # 类属性

    @classmethod
    def increment(cls):
        cls.total += 1  # 直接操作类属性

Counter.increment()  # 类名调用
print(Counter.total)  # 输出:1

obj = Counter()
obj.increment()       # 实例调用
print(Counter.total)  # 输出:2

类方法和静态方法有啥区别,什么场景下用哪个?

特性

​类方法

​静态方法

装饰器

@classmethod

@staticmethod

首参数

cls(绑定类)

无特殊参数

访问权限

可读写类属性,不可操作实例属性

无权限访问类或实例属性

典型应用场景

工厂方法、类状态管理

工具函数、数据校验

三、文件IO

1、使用的库

  • import os

2、常见的使用

(1)文件/文件夹是否存在

import os

file_path = "./example.txt"  # 文件夹:"./demo"

print(os.path.exists(file_path))
print(os.access(file_path, os.F_OK)) # 两种方式均可,存在True,不存在False

(2)是文件还是文件夹

import os

file_path = "./example.txt"

print(os.path.isfile(file_path)) # 是否为文件 True是 False否
print(os.path.isdir(file_path)) # 是否为文件夹 True是 False否

(3)获取文件的操作权限

import os

file_path = "./example.txt"
# 使用os.access(filename, mode)  mode的取值:
print(os.access(file_path, os.F_OK))   # 是否存在
print(os.access(file_path, os.R_OK))   # 是否可读
print(os.access(file_path, os.W_OK))   # 是否可写
print(os.access(file_path, os.EX_OK))  # 是否可执行

(4)创建文件夹/文件

import os

# 创建文件夹
dir_path = "./demo"

# 判断文件夹是否存在,存在就提示,不存在则创建
if os.path.exists(dir_path):
    print('demo文件夹存在')
else:
    os.mkdir(dir_path)  # 使用mkdir(path)适用于单层目录

dirs_path = "./demo/test/example"
os.makedirs(dirs_path) # 使用makedirs(path) 可创建多层目录

# 创建文件
file_path = "./example.txt"
open(file_path, "w") # 使用open的写入模式打开,文件若不存在会自动创建

(5)打开文件

(6)读取文件内容

import os

file_path = "./example.txt"

if os.path.exits(file_path):
    f = open(filename, 'r', encoding='UTF-8')  
    # 以r(只读)方式打开,且open默认使用GBK的方式来解析文件内容,
    # 有可能会报错UnicondeDecodeError,需要指定encoding编码
    content = f.read()  
    # 读取文件内容,read([size]) size参数可选,读取多长的内容,-1 = 全部,未指定 = 全部
    line = f.readLine() 
    # 读取一行内容,readLine([size]) size参数可选,在这一行中读取多长的内容
    lines = readLines()
    # 读取多行内容,默认读全部,每一行遇到\n结束,得到一个列表
    print(content, line, lines)

    for line in f:
        print(line)
    # 使用for循环遍历进行输出每一行
else:
    print('文件不存在')

(7)写入文件

import os

file_path = "./example.txt"

if os.path.exits(file_path):
    # 以w(可写)方式打开,光标会默认定位到文件开头,
    # 会覆盖原有的内容,但是同一条流不会被覆盖
    f = open(file_path, 'w', , encoding='UTF-8')
    f.write("example")    # write 用于写入文件
    # 以a(追加)的方式写入,光标默认定位到文件结尾。不会覆盖原有内容
    f1 = open(file_path, 'a', , encoding='UTF-8')  
    f1.write("test")

如果文件不存在的时候,哪种模式会自动帮我们创建文件并写入?

  • w模式、a模式、w+模式、a+模式和x模式,这几种模式会自动创建文件并写入,他们区别如下:

模式

创建文件

覆盖内容

支持读

指针位置

典型场景

w

开头

覆盖写入

a

末尾

追加日志

w+

开头

读写重建

a+

末尾

读写追加

x

开头

防重创建

(8)关闭文件

import os

file_path = "./example.txt"

if os.path.exits(file_path):
    f = open(file_path, 'w', , encoding='UTF-8')
    f.write("example")
    f.close()   # 使用close关闭文件
# 但手动写close很容易遗忘,推荐使用with,完成后会自动关闭文件
with open(file_path, 'a', , encoding='UTF-8') as file:  
    file.write("test")

(9)保存文件

# 保存字典数据到json文件
import json # 导入JSON库

user_info = {
    'name' = '张三',
    'age' = 20,
    'addr' = "厦门"
}

# open一个文件,我们要写入的文件,若不存在则创建
with open('./info.json', 'w', encoding='UTF-8') as file:
  # 将字典以json格式存入文件中
  json.dump(user_info, file, ensure_ascii=False, indent=4)  
# json.dump(obj, fp, ensure_ascii, indent)
# obj:要存入的字典数据,
# fp:要写入的目标文件,
# ensure_ascii:是否使用ascii编码(默认True会将中文进行编码,需要设为False)
# indent:缩进(让JSON文件内容更美观)
# 将数据保存到Excel表格
import pandas as pd # 该库擅长于数据分析和处理
import openpyxl # 该库擅长于处理美化excel表格格式(合并单元格等)

# 需要安装 pip install pandas openpyxl

# 方式1:pandas

# 创建一个数据
data = {
    'name': ['zhangsan', 'lisi'],
    'age': [18, 20]
}
# 使用pandas进行数据处理
df = pd.DataFrame(data)
# 将数据吸入Excel表格中
df.to_excel('./test.xlsx', index = False)  # index = False 关闭索引显示

# 方式2: openpyxl

from openpyxl import Workbook

# 创建新工作簿
workbook = Workbook()
sheet = workbook.active  # 获取默认工作表
# 写入表头
header = ["姓名", "部门", "工号", "入职日期"]
sheet.append(header)  # 批量写入表头
# 表格数据
employees = [
    ["张三", "技术部", "A001", "2023-03-01"],
    ["李四", "市场部", "B002", "2022-08-15"]
]
# 批量写入数据
for row in employees:
    sheet.append(row)  # 按行追加数据
# 保存文件
workbook.save("employee_data.xlsx")

(10)解析文件

  • 下一节敬请期待......

四、课后练习

1、OpenCV完成马赛克形式的打码

import cv2

def apply_mosaic(img, x, y, w, h, block_size=10):
    """给人脸区域打马赛克"""
    # 核心逻辑:缩小再放大实现像素块效果
    face_region = img[y:y + h, x:x + w]
    small = cv2.resize(face_region, (block_size, block_size), interpolation=cv2.INTER_NEAREST)
    mosaic = cv2.resize(small, (w, h), interpolation=cv2.INTER_NEAREST)
    mosaic = cv2.medianBlur(mosaic, 3)
    img[y:y + h, x:x + w] = mosaic
    return img

# 加载人脸检测模型
face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
# 读取图片并转灰度图
img = cv2.imread('images/face.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 检测人脸
faces = face_cascade.detectMultiScale(gray, 1.01, 18, minSize=(8, 8))
# 遍历所有人脸并处理
for (x, y, w, h) in faces:
    img = apply_mosaic(img, x, y, w, h)  # 打马赛克
# 显示结果
cv2.imshow('Result', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

2、定义一些数据,将数据保存到json、excel、csv

import json
import pandas as pd

# 定义数据
data = [
    {"姓名": "张三", "年龄": 25, "城市": "北京", "技能": ["Python", "Java"]},
    {"姓名": "李四", "年龄": 30, "城市": "上海", "技能": ["数据分析", "机器学习"]},
    {"姓名": "王五", "年龄": 28, "城市": "广州", "技能": ["Web开发", "数据库"]}
]

# 保存为JSON文件
with open('data.json', 'w', encoding='utf-8') as f:
    json.dump(data, f, ensure_ascii=False, indent=4)

# 保存为Excel文件
df = pd.DataFrame(data)
df.to_excel('data.xlsx', index=False, engine='openpyxl')

# 保存为CSV文件
df.to_csv('data.csv', index=False, encoding='utf-8-sig')