python 文件操作与异常处理-之十
·
第10:面向对象编程基础
目录
面向对象编程概述
面向对象编程(Object-Oriented Programming,OOP)是一种编程范式,它将现实世界中的事物抽象为对象,通过对象之间的交互来解决问题。
面向对象的核心概念
# 1. 类(Class):对象的模板或蓝图
# 2. 对象(Object):类的实例
# 3. 属性(Attribute):对象的特征或状态
# 4. 方法(Method):对象的行为或功能
# 5. 封装(Encapsulation):隐藏对象的内部实现细节
# 6. 继承(Inheritance):子类继承父类的属性和方法
# 7. 多态(Polymorphism):同一接口的不同实现
面向对象的优势
- 模块化:代码组织更清晰
- 可重用性:通过继承和组合重用代码
- 可维护性:修改局部不影响整体
- 可扩展性:容易添加新功能
类和对象
类是创建对象的模板,对象是类的实例。
定义类
# 定义一个简单的类
class Person:
"""人类"""
pass
# 创建对象(实例化)
person1 = Person()
person2 = Person()
print(type(person1)) # 输出:<class '__main__.Person'>
print(person1 is person2) # 输出:False(不同的对象)
类的基本结构
class Person:
"""人类类"""
# 类属性
species = "Homo sapiens"
# 初始化方法
def __init__(self, name, age):
# 实例属性
self.name = name
self.age = age
# 实例方法
def introduce(self):
return f"我是{self.name},今年{self.age}岁"
def have_birthday(self):
self.age += 1
return f"{self.name}现在{self.age}岁了"
# 创建对象并使用
person = Person("张三", 25)
print(person.introduce()) # 输出:我是张三,今年25岁
print(person.have_birthday()) # 输出:张三现在26岁了
属性和方法
属性是对象的特征,方法是对象的行为。
实例属性
class Car:
"""汽车类"""
def __init__(self, brand, model, year):
# 实例属性
self.brand = brand # 品牌
self.model = model # 型号
self.year = year # 年份
self.mileage = 0 # 里程(公里)
self.is_running = False # 是否运行中
# 创建汽车对象
car1 = Car("丰田", "卡罗拉", 2020)
car2 = Car("本田", "雅阁", 2021)
print(f"{car1.brand} {car1.model} {car1.year}年") # 输出:丰田 卡罗拉 2020年
print(f"{car2.brand} {car2.model} {car2.year}年") # 输出:本田 雅阁 2021年
实例方法
class Car:
"""汽车类"""
def __init__(self, brand, model, year):
self.brand = brand
self.model = model
self.year = year
self.mileage = 0
self.is_running = False
# 启动汽车
def start(self):
if not self.is_running:
self.is_running = True
return f"{self.brand} {self.model} 已启动"
else:
return f"{self.brand} {self.model} 已经在运行中"
# 停止汽车
def stop(self):
if self.is_running:
self.is_running = False
return f"{self.brand} {self.model} 已停止"
else:
return f"{self.brand} {self.model} 已经停止了"
# 行驶
def drive(self, distance):
if self.is_running:
self.mileage += distance
return f"行驶了{distance}公里,总里程{self.mileage}公里"
else:
return "请先启动汽车"
# 获取汽车信息
def get_info(self):
status = "运行中" if self.is_running else "已停止"
return f"{self.brand} {self.model} ({self.year}年) - 里程:{self.mileage}公里,状态:{status}"
# 使用汽车类
my_car = Car("丰田", "卡罗拉", 2020)
print(my_car.start()) # 输出:丰田 卡罗拉 已启动
print(my_car.drive(100)) # 输出:行驶了100公里,总里程100公里
print(my_car.drive(50)) # 输出:行驶了50公里,总里程150公里
print(my_car.get_info()) # 输出:丰田 卡罗拉 (2020年) - 里程:150公里,状态:运行中
print(my_car.stop()) # 输出:丰田 卡罗拉 已停止
构造方法和析构方法
构造方法用于初始化对象,析构方法用于清理资源。
构造方法 init
class Student:
"""学生类"""
def __init__(self, name, student_id, grades=None):
"""构造方法"""
self.name = name
self.student_id = student_id
self.grades = grades if grades is not None else []
print(f"创建学生对象:{self.name}")
def add_grade(self, subject, grade):
"""添加成绩"""
self.grades.append({"subject": subject, "grade": grade})
def get_average(self):
"""计算平均分"""
if not self.grades:
return 0
total = sum(grade["grade"] for grade in self.grades)
return total / len(self.grades)
# 创建学生对象
student = Student("张三", "2023001")
student.add_grade("数学", 85)
student.add_grade("英语", 90)
print(f"平均分:{student.get_average()}") # 输出:平均分:87.5
析构方法 del
class DatabaseConnection:
"""数据库连接类"""
def __init__(self, host, port):
self.host = host
self.port = port
print(f"连接到数据库 {host}:{port}")
def query(self, sql):
"""执行查询"""
return f"执行查询:{sql}"
def __del__(self):
"""析构方法"""
print(f"关闭数据库连接 {self.host}:{self.port}")
# 使用数据库连接
db = DatabaseConnection("localhost", 5432)
result = db.query("SELECT * FROM users")
print(result)
# 对象超出作用域时自动调用析构方法
# 注意:Python的垃圾回收机制可能会延迟析构方法的调用
封装
封装是将对象的内部实现细节隐藏起来,只暴露必要的接口。
访问控制
class BankAccount:
"""银行账户类"""
def __init__(self, account_number, initial_balance=0):
self.account_number = account_number # 公有属性
self._balance = initial_balance # 受保护属性(约定)
self.__pin = "1234" # 私有属性
# 公有方法
def deposit(self, amount):
"""存款"""
if amount > 0:
self._balance += amount
return f"存款成功,当前余额:{self._balance}"
return "存款金额必须大于0"
def withdraw(self, amount, pin):
"""取款"""
if pin != self.__pin:
return "密码错误"
if amount > self._balance:
return "余额不足"
self._balance -= amount
return f"取款成功,当前余额:{self._balance}"
def get_balance(self):
"""获取余额"""
return self._balance
# 私有方法
def __validate_pin(self, pin):
"""验证密码(私有方法)"""
return pin == self.__pin
# 使用银行账户
account = BankAccount("123456789", 1000)
print(account.deposit(500)) # 输出:存款成功,当前余额:1500
print(account.withdraw(200, "1234")) # 输出:取款成功,当前余额:1300
print(account.get_balance()) # 输出:1300
# 尝试直接访问私有属性(会出错)
# print(account.__pin) # AttributeError
# 但可以通过名称改写访问(不推荐)
# print(account._BankAccount__pin) # 输出:1234
属性装饰器
class Temperature:
"""温度类"""
def __init__(self, celsius=0):
self._celsius = celsius
@property
def celsius(self):
"""获取摄氏度"""
return self._celsius
@celsius.setter
def celsius(self, value):
"""设置摄氏度"""
if value < -273.15:
raise ValueError("温度不能低于绝对零度")
self._celsius = value
@property
def fahrenheit(self):
"""获取华氏度"""
return self._celsius * 9/5 + 32
@fahrenheit.setter
def fahrenheit(self, value):
"""设置华氏度"""
self.celsius = (value - 32) * 5/9
# 使用温度类
temp = Temperature(25)
print(f"摄氏度:{temp.celsius}") # 输出:摄氏度:25
print(f"华氏度:{temp.fahrenheit}") # 输出:华氏度:77.0
temp.fahrenheit = 86
print(f"摄氏度:{temp.celsius}") # 输出:摄氏度:30.0
# temp.celsius = -300 # 会抛出ValueError异常
继承
继承允许子类获得父类的属性和方法。
基本继承
# 父类(基类)
class Animal:
"""动物类"""
def __init__(self, name, species):
self.name = name
self.species = species
def make_sound(self):
return "动物发出声音"
def info(self):
return f"我是{self.name},属于{self.species}"
# 子类(派生类)
class Dog(Animal):
"""狗类"""
def __init__(self, name, breed):
super().__init__(name, "犬科") # 调用父类构造方法
self.breed = breed
# 重写父类方法
def make_sound(self):
return "汪汪汪!"
# 添加新方法
def wag_tail(self):
return f"{self.name}摇尾巴"
class Cat(Animal):
"""猫类"""
def __init__(self, name, color):
super().__init__(name, "猫科")
self.color = color
# 重写父类方法
def make_sound(self):
return "喵喵喵!"
# 添加新方法
def purr(self):
return f"{self.name}发出呼噜声"
# 使用继承
dog = Dog("旺财", "金毛")
cat = Cat("咪咪", "橘色")
print(dog.info()) # 输出:我是旺财,属于犬科
print(dog.make_sound()) # 输出:汪汪汪!
print(dog.wag_tail()) # 输出:旺财摇尾巴
print(cat.info()) # 输出:我是咪咪,属于猫科
print(cat.make_sound()) # 输出:喵喵喵!
print(cat.purr()) # 输出:咪咪发出呼噜声
多重继承
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.info()) # 输出:我是唐老鸭,属于鸭科
print(duck.make_sound()) # 输出:嘎嘎嘎!
print(duck.fly()) # 输出:正在飞行
print(duck.swim()) # 输出:正在游泳
多态
多态允许不同类的对象对同一消息做出不同的响应。
多态示例
class Shape:
"""形状基类"""
def area(self):
"""计算面积(抽象方法)"""
raise NotImplementedError("子类必须实现area方法")
def perimeter(self):
"""计算周长(抽象方法)"""
raise NotImplementedError("子类必须实现perimeter方法")
class Rectangle(Shape):
"""矩形类"""
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
class Circle(Shape):
"""圆形类"""
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14159 * self.radius ** 2
def perimeter(self):
return 2 * 3.14159 * self.radius
class Triangle(Shape):
"""三角形类"""
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def area(self):
# 使用海伦公式计算面积
s = (self.a + self.b + self.c) / 2
return (s * (s - self.a) * (s - self.b) * (s - self.c)) ** 0.5
def perimeter(self):
return self.a + self.b + self.c
# 多态的使用
shapes = [
Rectangle(5, 3),
Circle(4),
Triangle(3, 4, 5)
]
for shape in shapes:
print(f"形状类型:{type(shape).__name__}")
print(f"面积:{shape.area():.2f}")
print(f"周长:{shape.perimeter():.2f}")
print("-" * 20)
isinstance() 和 issubclass()
# 检查对象类型
rectangle = Rectangle(5, 3)
print(isinstance(rectangle, Rectangle)) # 输出:True
print(isinstance(rectangle, Shape)) # 输出:True
print(isinstance(rectangle, Circle)) # 输出:False
# 检查类继承关系
print(issubclass(Rectangle, Shape)) # 输出:True
print(issubclass(Circle, Shape)) # 输出:True
print(issubclass(Rectangle, Circle)) # 输出:False
特殊方法
特殊方法(魔术方法)允许我们自定义类的行为。
常用特殊方法
class Vector:
"""向量类"""
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
"""字符串表示"""
return f"Vector({self.x}, {self.y})"
def __repr__(self):
"""官方字符串表示"""
return f"Vector(x={self.x}, y={self.y})"
def __add__(self, other):
"""加法运算"""
if isinstance(other, Vector):
return Vector(self.x + other.x, self.y + other.y)
return NotImplemented
def __sub__(self, other):
"""减法运算"""
if isinstance(other, Vector):
return Vector(self.x - other.x, self.y - other.y)
return NotImplemented
def __mul__(self, scalar):
"""数乘运算"""
if isinstance(scalar, (int, float)):
return Vector(self.x * scalar, self.y * scalar)
return NotImplemented
def __eq__(self, other):
"""相等比较"""
if isinstance(other, Vector):
return self.x == other.x and self.y == other.y
return False
def __len__(self):
"""长度(返回维度数)"""
return 2
def __getitem__(self, index):
"""索引访问"""
if index == 0:
return self.x
elif index == 1:
return self.y
else:
raise IndexError("向量只有两个元素")
def __setitem__(self, index, value):
"""索引赋值"""
if index == 0:
self.x = value
elif index == 1:
self.y = value
else:
raise IndexError("向量只有两个元素")
# 使用向量类
v1 = Vector(3, 4)
v2 = Vector(1, 2)
print(str(v1)) # 输出:Vector(3, 4)
print(repr(v1)) # 输出:Vector(x=3, y=4)
v3 = v1 + v2
print(v3) # 输出:Vector(4, 6)
v4 = v1 - v2
print(v4) # 输出:Vector(2, 2)
v5 = v1 * 3
print(v5) # 输出:Vector(9, 12)
print(v1 == v2) # 输出:False
print(len(v1)) # 输出:2
print(v1[0], v1[1]) # 输出:3 4
v1[0] = 5
print(v1) # 输出:Vector(5, 4)
类属性和类方法
类属性属于类本身,类方法操作类属性。
类属性
class Employee:
"""员工类"""
# 类属性
company_name = "科技有限公司"
employee_count = 0
def __init__(self, name, position, salary):
self.name = name
self.position = position
self.salary = salary
# 每创建一个员工,员工计数加1
Employee.employee_count += 1
def get_info(self):
return f"{self.name} - {self.position} - {self.salary}元"
@classmethod
def get_company_name(cls):
"""类方法:获取公司名称"""
return cls.company_name
@classmethod
def get_employee_count(cls):
"""类方法:获取员工总数"""
return cls.employee_count
@classmethod
def set_company_name(cls, name):
"""类方法:设置公司名称"""
cls.company_name = name
# 使用类属性和类方法
emp1 = Employee("张三", "程序员", 10000)
emp2 = Employee("李四", "设计师", 8000)
emp3 = Employee("王五", "产品经理", 12000)
print(Employee.get_company_name()) # 输出:科技有限公司
print(Employee.get_employee_count()) # 输出:3
print(emp1.get_employee_count()) # 输出:3
# 修改类属性
Employee.set_company_name("新科技有限公司")
print(Employee.get_company_name()) # 输出:新科技有限公司
print(emp1.get_company_name()) # 输出:新科技有限公司
静态方法
静态方法不访问类或实例的属性,类似于普通函数。
class MathUtils:
"""数学工具类"""
@staticmethod
def add(a, b):
"""加法"""
return a + b
@staticmethod
def multiply(a, b):
"""乘法"""
return a * b
@staticmethod
def is_even(number):
"""判断是否为偶数"""
return number % 2 == 0
@staticmethod
def factorial(n):
"""计算阶乘"""
if n < 0:
raise ValueError("阶乘不能为负数")
if n == 0 or n == 1:
return 1
result = 1
for i in range(2, n + 1):
result *= i
return result
# 使用静态方法
print(MathUtils.add(5, 3)) # 输出:8
print(MathUtils.multiply(4, 6)) # 输出:24
print(MathUtils.is_even(10)) # 输出:True
print(MathUtils.factorial(5)) # 输出:120
# 静态方法可以通过类名或实例调用
utils = MathUtils()
print(utils.add(2, 3)) # 输出:5
实际应用示例
# 图书管理系统
class Book:
"""图书类"""
def __init__(self, isbn, title, author, publication_year):
self.isbn = isbn
self.title = title
self.author = author
self.publication_year = publication_year
self.is_borrowed = False
self.borrower = None
def __str__(self):
status = "已借出" if self.is_borrowed else "在馆"
return f"《{self.title}》 - {self.author} ({self.publication_year}) [{status}]"
def borrow(self, borrower_name):
"""借书"""
if self.is_borrowed:
return f"《{self.title}》已被{self.borrower}借阅"
self.is_borrowed = True
self.borrower = borrower_name
return f"《{self.title}》借阅成功,借阅人:{borrower_name}"
def return_book(self):
"""还书"""
if not self.is_borrowed:
return f"《{self.title}》未被借阅"
borrower = self.borrower
self.is_borrowed = False
self.borrower = None
return f"《{self.title}》归还成功,归还人:{borrower}"
class Library:
"""图书馆类"""
def __init__(self, name):
self.name = name
self.books = []
self.members = []
def add_book(self, book):
"""添加图书"""
self.books.append(book)
return f"图书《{book.title}》已添加到图书馆"
def remove_book(self, isbn):
"""移除图书"""
for i, book in enumerate(self.books):
if book.isbn == isbn:
removed_book = self.books.pop(i)
return f"图书《{removed_book.title}》已从图书馆移除"
return "未找到指定ISBN的图书"
def find_book(self, keyword):
"""查找图书"""
results = []
for book in self.books:
if (keyword in book.title or
keyword in book.author or
keyword == book.isbn):
results.append(book)
return results
def list_books(self):
"""列出所有图书"""
if not self.books:
return "图书馆暂无图书"
return "\n".join(str(book) for book in self.books)
def borrow_book(self, isbn, borrower_name):
"""借书"""
for book in self.books:
if book.isbn == isbn:
return book.borrow(borrower_name)
return "未找到指定ISBN的图书"
def return_book(self, isbn):
"""还书"""
for book in self.books:
if book.isbn == isbn:
return book.return_book()
return "未找到指定ISBN的图书"
# 使用图书管理系统
library = Library("城市图书馆")
# 添加图书
book1 = Book("978-7-111-2635-0", "Python编程:从入门到实践", "埃里克·马瑟斯", 2019)
book2 = Book("978-7-115-42802-8", "流畅的Python", "卢西亚诺·拉马略", 2017)
book3 = Book("978-7-111-52824-5", "Python核心编程", "韦斯利·春", 2016)
library.add_book(book1)
library.add_book(book2)
library.add_book(book3)
print("图书馆图书列表:")
print(library.list_books())
print()
# 借书
print(library.borrow_book("978-7-111-2635-0", "张三"))
print(library.borrow_book("978-7-115-42802-8", "李四"))
print()
print("借阅后的图书状态:")
print(library.list_books())
print()
# 还书
print(library.return_book("978-7-111-2635-0"))
print()
print("还书后的图书状态:")
print(library.list_books())
print()
# 查找图书
print("查找'Python'相关图书:")
results = library.find_book("Python")
for book in results:
print(book)
总结
本篇教程详细介绍了面向对象编程的基础知识,包括类和对象、属性和方法、构造方法和析构方法、封装、继承、多态、特殊方法、类属性和类方法、静态方法等内容。
掌握面向对象编程是成为优秀Python程序员的重要一步,它能够帮助我们编写更加模块化、可重用和可维护的代码。
更多推荐

所有评论(0)