2.2.1 面向对象编程概述
在Python编程中,面向对象编程(Object-Oriented Programming,简称OOP)是一种重要的编程思想,它将数据和操作数据的方法封装在一起,提高了代码的复用性、可维护性和扩展性。而Class(类)正是面向对象编程的核心概念,就像现实世界中的“模板”,能够帮助我们快速创建具有相同属性和行为的对象。
面向对象的核心概念
- 类(Class):定义对象的属性和方法的模板
- 对象(Object):类的实例,具有具体的属性和行为
- 封装(Encapsulation):将数据和方法封装在类中
- 继承(Inheritance):子类继承父类的属性和方法
- 多态(Polymorphism):不同对象对同一方法的不同响应
2.2.2 什么是Class(类)?
类是对现实世界中某一类事物的抽象描述。比如“动物”可以看作一个类,它包含了所有动物共有的属性(如名称、年龄、颜色)和行为(如吃饭、睡觉、移动)。在Python中,我们通过class关键字来定义一个类,基本语法如下:
class 类名:
# 类的属性和方法
pass
例如,定义一个“狗”类:
class Dog:
# 属性:品种、年龄、颜色
breed = "金毛"
age = 2
color = "金黄色"
# 方法: bark(吠叫)、run(奔跑)
def bark(self):
print("汪汪叫")
def run(self):
print("飞快地跑")
这里的breed、age、color是类的属性,bark和run是类的方法(即类中定义的函数),self是一个特殊参数,代表类的实例本身,在调用方法时不需要手动传递。
- 类名使用
CamelCase(驼峰命名法) - 方法名和属性名使用
snake_case(下划线命名法)
2.2.3 从类到对象:实例化过程
类只是一个“模板”,要使用类的功能,需要创建类的实例(即对象),这个过程称为“实例化”。实例化的语法非常简单,只需像调用函数一样使用类名即可:
# 创建Dog类的实例(对象)
my_dog = Dog()
# 访问对象的属性
print(my_dog.breed) # 输出:金毛
print(my_dog.age) # 输出:2
# 调用对象的方法
my_dog.bark() # 输出:汪汪叫
my_dog.run() # 输出:飞快地跑
通过实例化,我们可以从一个类创建多个不同的对象,每个对象都可以有自己独特的属性值。例如,再创建一只“泰迪”:
your_dog = Dog()
your_dog.breed = "泰迪"
your_dog.age = 1
your_dog.color = "棕色"
print(your_dog.breed) # 输出:泰迪
your_dog.bark() # 输出:汪汪叫(方法行为相同)
2.2.4 __init__方法:初始化对象属性
在上面的例子中,我们需要手动为每个对象修改属性,不够高效。Python提供了__init__方法(构造方法),用于在实例化对象时自动初始化属性。__init__方法会在对象创建时自动调用,语法如下:
class 类名:
def __init__(self, 参数1, 参数2, ...):
self.属性1 = 参数1
self.属性2 = 参数2
...
以“狗”类为例,使用__init__方法优化:
class Dog:
def __init__(self, breed, age, color):
self.breed = breed # 实例属性:品种
self.age = age # 实例属性:年龄
self.color = color # 实例属性:颜色
def bark(self):
print(f"{self.breed}在汪汪叫")
def run(self):
print(f"{self.age}岁的{self.breed}飞快地跑")
# 实例化对象时传递参数
my_dog = Dog("金毛", 2, "金黄色")
your_dog = Dog("泰迪", 1, "棕色")
my_dog.bark() # 输出:金毛在汪汪叫
your_dog.run() # 输出:1岁的泰迪飞快地跑
__init__方法中的self.breed等称为“实例属性”,每个对象的实例属性可以不同,而类中直接定义的属性(如之前的breed = "金毛")称为“类属性”,所有对象共享同一值。
2.2.5 面向对象的三大特性
1 封装
封装是指将对象的属性和方法隐藏在类内部,只提供有限的接口供外部访问。通过封装,可以保护数据不被随意修改,提高代码的安全性。在Python中,通常通过在属性或方法名前加双下划线__来实现私有性(伪私有,实际可通过特殊方式访问,但不推荐):
class Person:
def __init__(self, name, age):
self.name = name # 公开属性
self.__age = age # 私有属性
def get_age(self): # 提供接口访问私有属性
return self.__age
def set_age(self, new_age): # 提供接口修改私有属性
if new_age > 0 and new_age < 150:
self.__age = new_age
else:
print("年龄输入无效")
p = Person("小明", 18)
print(p.name) # 输出:小明
print(p.get_age()) # 输出:18
p.set_age(20)
print(p.get_age()) # 输出:20
# print(p.__age) # 报错,无法直接访问私有属性
2 继承
继承是指一个类(子类)可以继承另一个类(父类)的属性和方法,并可以在此基础上添加新的属性或方法,或重写父类的方法。继承可以减少代码重复,实现代码复用:
class Animal: # 父类
def __init__(self, name):
self.name = name
def eat(self):
print(f"{self.name}在吃东西")
class Dog(Animal): # 子类继承父类
def bark(self):
print(f"{self.name}在汪汪叫")
class Cat(Animal): # 另一个子类
def meow(self):
print(f"{self.name}在喵喵叫")
def eat(self): # 重写父类方法
print(f"{self.name}在吃鱼")
dog = Dog("旺财")
dog.eat() # 输出:旺财在吃东西(继承父类方法)
dog.bark() # 输出:旺财在汪汪叫(子类新增方法)
cat = Cat("咪宝")
cat.eat() # 输出:咪宝在吃鱼(重写后的方法)
cat.meow() # 输出:咪宝在喵喵叫
2.5 多继承
class Flyable:
"""可飞行接口"""
def fly(self):
return "飞行中"
class Swimmable:
"""可游泳接口"""
def swim(self):
return "游泳中"
class Duck(Animal, Flyable, Swimmable):
"""鸭子类,多继承"""
def __init__(self, name):
super().__init__(name, "鸭科")
def make_sound(self):
return "嘎嘎嘎"
# 使用示例
duck = Duck("唐老鸭")
print(duck.make_sound()) # 嘎嘎嘎
print(duck.fly()) # 飞行中
print(duck.swim()) # 游泳中
3 多态
多态是指不同的对象调用相同的方法时,会表现出不同的行为。多态依赖于继承和方法重写,它让代码更加灵活:
# 多态函数
def animal_sound(animal): # 接收Animal类或其子类的对象
if isinstance(animal, Dog):
animal.bark()
elif isinstance(animal, Cat):
animal.meow()
dog = Dog("旺财")
cat = Cat("咪宝")
animal_sound(dog) # 输出:旺财在汪汪叫
animal_sound(cat) # 输出:咪宝在喵喵叫
核心概念
多态性(Polymorphism)
- 定义:同一个接口可以处理不同类型的对象
- 体现:animal_sound() 函数可以接收不同类型的动物对象
- 优势:代码更灵活,易于扩展
继承(Inheritance)
- Dog 和 Cat 都继承自 Animal 类
- 子类可以使用父类的属性和方法
- Cat 类重写了 eat() 方法,体现了方法重写
类型检查 - isinstance(animal, Dog) 检查对象是否为 Dog 类型
- isinstance(animal, Cat) 检查对象是否为 Cat 类型
- 根据对象类型调用相应的方法
2.2.6 实际案例
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
SRE运维监控告警系统 - 多态性实际案例
演示不同类型的告警处理器如何通过统一接口处理
"""
import time
from abc import ABC, abstractmethod
from typing import Dict, Any
class AlertHandler(ABC): # 抽象基类
"""告警处理器抽象基类"""
def __init__(self, name: str):
self.name = name
self.alert_count = 0
@abstractmethod
def send_alert(self, message: str, level: str) -> bool:
"""发送告警的抽象方法"""
pass
def get_stats(self) -> Dict[str, Any]:
"""获取统计信息"""
return {
"name": self.name,
"alert_count": self.alert_count,
"type": self.__class__.__name__
}
class EmailAlertHandler(AlertHandler): # 邮件告警处理器
"""邮件告警处理器"""
def __init__(self, name: str, smtp_server: str, recipients: list):
super().__init__(name)
self.smtp_server = smtp_server
self.recipients = recipients
def send_alert(self, message: str, level: str) -> bool:
"""发送邮件告警"""
self.alert_count += 1
print(f"📧 [邮件告警] 通过 {self.smtp_server} 发送到 {self.recipients}")
print(f" 级别: {level}")
print(f" 内容: {message}")
print(f" 时间: {time.strftime('%Y-%m-%d %H:%M:%S')}")
return True
class SlackAlertHandler(AlertHandler): # Slack告警处理器
"""Slack告警处理器"""
def __init__(self, name: str, webhook_url: str, channel: str):
super().__init__(name)
self.webhook_url = webhook_url
self.channel = channel
def send_alert(self, message: str, level: str) -> bool:
"""发送Slack告警"""
self.alert_count += 1
print(f"💬 [Slack告警] 发送到频道 {self.channel}")
print(f" Webhook: {self.webhook_url}")
print(f" 级别: {level}")
print(f" 内容: {message}")
print(f" 时间: {time.strftime('%Y-%m-%d %H:%M:%S')}")
return True
class DingTalkAlertHandler(AlertHandler): # 钉钉告警处理器
"""钉钉告警处理器"""
def __init__(self, name: str, webhook_url: str, at_mobiles: list = None):
super().__init__(name)
self.webhook_url = webhook_url
self.at_mobiles: list = at_mobiles if at_mobiles is not None else []
def send_alert(self, message: str, level: str) -> bool:
"""发送钉钉告警"""
self.alert_count += 1
print(f"📱 [钉钉告警] 发送到群组")
print(f" Webhook: {self.webhook_url}")
print(f" 级别: {level}")
print(f" 内容: {message}")
print(f" @手机号: {self.at_mobiles}")
print(f" 时间: {time.strftime('%Y-%m-%d %H:%M:%S')}")
return True
class MonitoringSystem:
"""监控系统 - 使用多态性处理不同类型的告警"""
def __init__(self):
self.alert_handlers = []
def add_handler(self, handler: AlertHandler):
"""添加告警处理器"""
self.alert_handlers.append(handler)
print(f"✅ 添加告警处理器: {handler.name} ({handler.__class__.__name__})")
def send_alert(self, message: str, level: str = "INFO"):
"""发送告警到所有处理器 - 多态性的体现"""
print(f"\n🚨 发送告警: {level} - {message}")
print("=" * 50)
success_count = 0
for handler in self.alert_handlers:
try:
if handler.send_alert(message, level):
success_count += 1
print("-" * 30)
except Exception as e:
print(f"❌ 处理器 {handler.name} 发送失败: {e}")
print(f"📊 告警发送完成: {success_count}/{len(self.alert_handlers)} 成功")
def get_all_stats(self):
"""获取所有处理器的统计信息"""
print("\n📈 告警处理器统计信息:")
print("=" * 50)
for handler in self.alert_handlers:
stats = handler.get_stats()
print(f"📊 {stats['name']} ({stats['type']}): {stats['alert_count']} 条告警")
def main():
"""主函数 - 演示多态性的实际应用"""
print("🔧 SRE运维监控告警系统 - 多态性演示")
print("=" * 60)
# 创建监控系统
monitoring = MonitoringSystem()
# 添加不同类型的告警处理器
email_handler = EmailAlertHandler(
name="生产环境邮件告警",
smtp_server="smtp.company.com",
recipients=["ops@company.com", "admin@company.com"]
)
slack_handler = SlackAlertHandler(
name="开发团队Slack告警",
webhook_url="https://hooks.slack.com/services/T123456/B789012/abcdef",
channel="#alerts"
)
dingtalk_handler = DingTalkAlertHandler(
name="运维团队钉钉告警",
webhook_url="https://oapi.dingtalk.com/robot/send?access_token=abc123",
at_mobiles=["13800138000", "13900139000"]
)
# 添加处理器到监控系统
monitoring.add_handler(email_handler)
monitoring.add_handler(slack_handler)
monitoring.add_handler(dingtalk_handler)
print("\n" + "=" * 60)
# 模拟不同类型的告警
alerts = [
("CPU使用率超过90%", "WARNING"),
("数据库连接池耗尽", "CRITICAL"),
("磁盘空间不足", "ERROR"),
("服务响应时间过长", "INFO")
]
for message, level in alerts:
monitoring.send_alert(message, level)
time.sleep(1) # 模拟处理时间
# 显示统计信息
monitoring.get_all_stats()
if __name__ == "__main__":
main()
评论区