深入浅出一下Python面向对象编程的核心概念与实践应用
本篇技术博文摘要 🌟
- 本文系统讲解了Python面向对象编程的核心概念与实践应用。通过电商系统用户订单模拟、动态权限账户系统等案例,深入剖析了类与对象、属性方法、实例方法等基础要素。
- 重点解析了
__init__
构造方法、__str__
对象描述、__lt__
比较运算符等魔法方法的应用场景,并以分数排序、手机价格输出等示例演示其实现逻辑。针对封装特性,详细阐述了通过私有属性/方法实现数据库安全连接、温度状态判断等典型封装模式,展示了属性访问控制与数据隐藏的核心优势。- 最后通过长方形面积计算、玩家背包系统等实战代码,完整呈现面向对象三大特性在Python中的工程化实现路径,帮助开发者构建高内聚、可扩展的应用系统。
引言 📘
- 在这个变幻莫测、快速发展的技术时代,与时俱进是每个IT工程师的必修课。
- 我是盛透侧视攻城狮,一名什么都会一丢丢的网络安全工程师,也是众多技术社区的活跃成员以及多家大厂官方认可人员,希望能够与各位在此共同成长。
上节回顾
目录
本篇技术博文摘要 🌟
引言 📘
上节回顾
01-面向对象的引入
原理:
作用:
一个基本的电商系统的用户和订单模拟代码示例:
02-面向对象
原理:
实现一个支持动态扩展权限的账户系统
03-属性方法
原理:
作用:
输出当前时间戳
04-实例方法
交易记录代码实现
05-实例属性
代码实现查看玩家背包物品数量
06- init
原理:
作用:
07- str.py
实现输出手机价格
08- lt
作用:
通过_it_代码实现分数排序后学生的姓名列表
10-私有属性& 私有方法
私有属性
私有方法:
通过 私有属性& 私有方法实现数据库连接和查询的功能
11-封装
通过封装实现打印长方形面积
通过封装实现温度判断:
欢迎各位彦祖与热巴畅游本人专栏与技术博客
你的三连是我最大的动力
点击➡️指向的专栏名即可闪现
01-面向对象的引入
原理:
- 面向对象编程(OOP)通过“对象”抽象现实世界,核心概念包括类(模板)和对象(实例)。OOP 的四大特性:封装、继承、多态、抽象。
作用:
- 提高代码复用性、可维护性和扩展性,适用于复杂系统建模
一个基本的电商系统的用户和订单模拟代码示例:
# 定义商品类
class Item:
def __init__(self, name, price):
self.name = name # 商品名称
self.price = price # 商品价格
# 定义用户类
class User:
def __init__(self, name, email):
self.name = name # 用户名
self.email = email # 用户邮箱
# 定义订单类
class Order:
def __init__(self, user, items):
self.user = user # 订单对应的用户
self.items = items # 订单中的商品列表
# 计算订单总价
def total_price(self):
return sum(item.price for item in self.items) # 返回所有商品价格的总和
# 示例使用
# 创建一个用户对象
user = User("Alice", "alice@example.com")
# 创建商品对象列表并组成一个订单
order = Order(user, [Item("Book", 30), Item("Pen", 5)])
# 打印订单总价
print(order.total_price())
02-面向对象
原理:
通过
class
关键字定义类,使用self
引用实例自身。类可以包含属性(数据)和方法(函数)。其实就是把功能和数据封装成为一个整体
作用:
- 实现数据与行为的绑定,构建高内聚模块。
实现一个支持动态扩展权限的账户系统
# 定义账户类
class Account:
def __init__(self, username, role="user"):
self.username = username # 账户的用户名
self._role = role # 账户的角色,默认是普通用户
self._permissions = [] # 账户的权限列表,默认没有权限
# 给账户添加权限,只有管理员可以添加权限
def add_permission(self, permission):
if self._role == "admin": # 判断角色是否是管理员
self._permissions.append(permission) # 如果是管理员,添加权限
else:
raise PermissionError("仅管理员可添加权限") # 普通用户不能添加权限,抛出错误
# 查看当前账户的权限
def get_permissions(self):
return self._permissions # 返回账户的权限列表
# 修改账户的角色
def set_role(self, role):
self._role = role # 可以修改账户角色(比如将用户变成管理员)
# 示例使用
# 创建一个管理员账户
admin = Account("admin", role="admin")
# 管理员账户添加权限
admin.add_permission("only-admin-persion") # 管理员可以添加权限
# 查看管理员权限
print(admin.get_permissions())
# 创建一个普通用户账户
user = Account("user", role="user")
# 普通用户尝试添加权限(会抛出错误)
try:
user.add_permission("view_reports")
except PermissionError as e:
print(e)
class Person(object):
def __init__(self,uname,age):
self.uname = uname
self.age = age
def person(self):
print(f"我的姓名是{self.uname},我的年龄是{self.age}")
a = Person("zhangsan",21)
a.person()
b = Person("lisi",22)
03-属性方法
原理:
- 类属性是所有实例共享的属性,类方法(
@classmethod
)操作类属性,静态方法(@staticmethod
)与类和实例无关。
作用:
- 管理类级别数据或工具函数
输出当前时间戳
# 定义一个 Logger 类,用于管理日志级别和生成时间戳
class Logger:
# 类属性 _log_level 存储日志的默认级别,默认为 "INFO"
_log_level = "INFO" # 类属性
# 定义一个类方法 set_log_level,允许修改日志级别
@classmethod
def set_log_level(cls, level):
"""
该方法是一个类方法,允许我们通过类名修改 _log_level 属性。
:param level: 要设置的日志级别,字符串类型(如 "INFO", "DEBUG", "ERROR" 等)
"""
# 修改类属性 _log_level 的值为传入的 level
cls._log_level = level
# 定义一个静态方法 timestamp,用于生成当前的时间戳
@staticmethod
def timestamp():
"""
该方法是一个静态方法,用于获取当前时间的 ISO 格式时间戳。
:return: 返回一个字符串,表示当前时间的 ISO 8601 格式
"""
# 导入 datetime 模块并返回当前时间的 ISO 8601 格式时间戳
import datetime
return datetime.datetime.now().isoformat()
# 调用 Logger 类的 set_log_level 方法设置日志级别为 "DEBUG"
Logger.set_log_level("DEBUG")
# 输出当前时间的时间戳,调用 timestamp 静态方法
print(Logger.timestamp())
04-实例方法
原理:
- 实例方法通过
self
访问实例属性,通常用于操作或修改实例状态。
作用:
- 定义对象的行为逻辑。
交易记录代码实现
# 定义一个 BankAccount 类,表示银行账户
class BankAccount:
# 构造方法,用于初始化银行账户余额
def __init__(self, balance=0):
"""
初始化银行账户对象,默认为余额为 0。
:param balance: 账户的初始余额,默认为 0
"""
# 将余额存储在实例属性 balance 中
self.balance = balance
# 存款方法,用于向账户中存入一定金额
def deposit(self, amount):
"""
存款方法,用于向银行账户中存入金额。
:param amount: 存款的金额,必须为正数
"""
# 如果存款金额大于 0,才进行存款操作
if amount > 0:
# 增加账户余额
self.balance += amount
# 调用私有方法 _log_transaction 记录存款操作
self._log_transaction(f"存款: +{amount}")
# 私有方法,用于记录交易信息(例如存款操作)
def _log_transaction(self, message):
"""
记录银行账户的交易操作,通常用于输出日志。
:param message: 交易的具体描述信息
"""
# 打印交易记录,输出操作信息
print(f"交易记录: {message}")
# 创建一个银行账户实例,初始余额为 0
account = BankAccount()
# 调用 deposit 方法向账户中存入 100 元
account.deposit(100)
class Cat(object):
def eat(self,name):
print(f"{name}在吃饭")
def drink(self,name):
print(f"{name}在喝水")
def introduce(self,uname,age):
print(f"我{uname},今年{age}岁了")
xiaohuamao = Cat()
xiaohuamao.eat("小花猫")
xiaohuamao.drink("小花猫")
xiaohuamao.introduce("小花猫",2)
Tom = Cat()
Tom.eat("TOM")
Tom.drink("tom")
Tom.introduce("Tom",5)
05-实例属性
原理:
- 实例属性属于特定对象,通过
self.属性名
定义,不同实例的属性相互独立。
作用:
- 存储对象的状态信息
代码实现查看玩家背包物品数量
# 定义一个 Player 类,表示一个玩家
class Player:
# 构造方法,用于初始化玩家对象
def __init__(self, name):
"""
初始化玩家对象,并设置玩家名字和背包。
:param name: 玩家名字
"""
self.name = name # 将传入的玩家名字赋值给实例属性 name
self.inventory = {} # 创建一个空字典,用于存储玩家的物品,物品名称作为键,数量作为值
# 添加物品到背包的方法
def add_item(self, item, quantity=1):
"""
向玩家的背包中添加物品。
:param item: 物品名称
:param quantity: 物品的数量,默认为 1
"""
# 使用 .get() 方法获取当前物品的数量,如果物品不存在,则默认为 0,然后加上新增的数量
self.inventory[item] = self.inventory.get(item, 0) + quantity
# 创建一个名为 Alice 的玩家实例
player1 = Player("Alice")
# 向 Alice 的背包中添加一个名为 "sword" 的物品
player1.add_item("sword")
# 打印 Alice 的背包,查看背包中物品的数量
print(player1.inventory)
06- init
原理:
__init__.py
文件标识一个目录为 Python 包,可包含包的初始化代码或定义__all__
列表控制导入行为。__init__:在对象刚刚穿件成功的时候,进行初始化设置,会自动执行这个方法
作用:
- 模块化代码,支持层级化导入
# 目录结构:
# my_package/
# __init__.py
# module1.py
# module2.py
# __init__.py 内容:
__all__ = ["module1"] # 仅允许导入 module1
from .module1 import func1
# 外部使用:
from my_package import func1 # 合法
from my_package import module2 # 报错
# __init__
class Person():
def __init__(self,name):
self.uname = name
def say_hi(self):
print(f"我的名字是{self.uname}")
a = Person("zhangsan")
a.say_hi()
07- str
原理:
__str__
方法定义对象的字符串表示形式,通过print(obj)
或str(obj)
调用。
作用:
- 提升调试和日志输出的可读性
实现输出手机价格
# 定义一个 Product 类,表示一个商品
class Product:
# 初始化方法 __init__,用于创建实例时设置商品的名称和价格
def __init__(self, name, price):
# 将传入的参数 name 和 price 分别赋值给当前实例的 name 和 price 属性
self.name = name # 商品的名称
self.price = price # 商品的价格
# 定义 __str__ 方法,用于当我们打印该类的实例时返回的字符串表示
def __str__(self):
# 通过格式化字符串返回商品的名称和价格,价格保留两位小数
return f"Product: {self.name}, 价格: ¥{self.price:.2f}"
# 创建一个 Product 类的实例,商品名称为 "手机",价格为 4999 元
product = Product("手机", 4999)
# 打印 product 实例
# 当打印对象时,Python 会自动调用该对象的 __str__ 方法,返回自定义的字符串表示
print(product) #
08- lt
原理:
__lt__
方法定义对象的小于比较行为(<
),其他比较方法如__eq__
、__gt__
类似。
作用:
- 支持对象间的自定义排序逻辑
通过_it_代码实现分数排序后学生的姓名列表
# 定义一个 Student 类,表示一个学生对象
class Student:
# 初始化方法 __init__,用于创建实例时设置学生的姓名和分数
def __init__(self, name, score):
# 将传入的参数 name 和 score 分别赋值给当前实例的 name 和 score 属性
self.name = name # 学生的姓名
self.score = score # 学生的分数
# 定义 __lt__ 方法,用于小于符号 (<) 的比较操作
def __lt__(self, other):
# 返回当前学生的分数是否小于另一个学生的分数
return self.score < other.score
# 创建一个学生对象列表,每个学生对象包括姓名和分数
students = [
Student("Bob", 85), # 创建一个学生 Bob,分数为 85
Student("Alice", 90) # 创建一个学生 Alice,分数为 90
]
# 使用 sorted 函数对学生列表进行排序,按照学生的分数升序排序
sorted_students = sorted(students) # 默认使用 __lt__ 方法进行排序
# 输出排序后学生的姓名列表
# sorted_students 已经按分数升序排序,现在提取每个学生的姓名并返回一个列表
print([s.name for s in sorted_students])
10-私有属性& 私有方法
原理:
- 在属性或方法名前加双下划线
__
实现私有化,外部无法直接访问(实际通过名称修饰访问,如_ClassName__method
)。- python中的私有,事实上都是假的,只是对私有(属性及方法)进行了重命名 将__属性名改为_类名__属性名
作用:
- 封装敏感数据或内部实现细节
私有属性
class Cat:
def __init__(self,name,age):
self.name = name
self.__age = age
#_Cat__age
def print_info(self):
print(self.name,self.__age)
tom = Cat("TOM",5)
# tom.__age = -10
# print(tom._Cat__age)
# tom.print_info()
print(tom._Cat__age)
私有方法:
class Cat:
def __init__(self,name,age):
self.name = name
self.__age = age
#_Cat__age
def print_info(self):
print(self.name,self.__age)
def __mimi(self):
print("这是我的树洞,你滴走开")
a = Cat("tom",12)
a._Cat__mimi()
通过 私有属性& 私有方法实现数据库连接和查询的功能
# 定义一个 Database 类,表示一个数据库操作的类
class Database:
# 初始化方法 __init__,用于创建实例时设置私有属性
def __init__(self):
# __credentials 是一个私有属性,存储数据库的连接凭证
self.__credentials = "user:password@localhost" # 私有属性,外部无法直接访问
# __connect 是一个私有方法,用于模拟数据库连接的过程
def __connect(self): # 私有方法,外部无法直接调用
print("连接数据库中...") # 打印连接数据库的提示信息
# query 是一个公共方法,用于执行数据库查询操作
def query(self, sql):
# 调用私有的 __connect 方法,进行数据库连接
self.__connect()
# 打印执行的查询 SQL 语句
print(f"执行查询: {sql}")
# 创建 Database 类的实例 db
db = Database()
# 正常调用公共方法 query,执行 SQL 查询
db.query("SELECT * FROM users") # 输出: "连接数据库中..." 和 "执行查询: SELECT * FROM users"
# 尝试访问私有属性 __credentials,会引发错误
print(db.__credentials) # 报错:AttributeError
11-封装
原理:
- 封装通过私有属性和公共方法控制数据访问,确保数据安全性。
- 真正意义上的封装:将类的属性封装隐藏,提供公开的方法(getter)和(setter)来访问
作用:
- 隐藏实现细节,暴露必要接口。
通过封装实现打印长方形面积
# 定义一个 Person 类
class Person(object):
# 构造函数:初始化宽度和高度
def __init__(self, width, height):
self.__width = width # 私有属性,宽度
self.__height = height # 私有属性,高度
# getter 方法:获取宽度
def getter_width(self):
return self.__width # 返回宽度
# setter 方法:设置宽度
def setter_width(self, width):
self.__width = width # 设置宽度
# 使用 @property 装饰器,将 height 方法变成属性,能够像访问属性一样调用它
@property
def height(self):
return self.__height # 返回高度
# 使用 @height.setter 装饰器,允许修改 height 属性的值
@height.setter
def height(self, height):
self.__height = height # 设置高度
# 打印宽度与高度的乘积,即面积
def print_01(self):
print(self.__width * self.__height)
# 将 getter 和 setter 方法绑定到属性上,这样我们可以通过 Person 类的实例直接访问 width 属性
width = property(getter_width, setter_width)
通过封装实现温度判断:
class TemperatureSensor:
def __init__(self):
self.__temperature = 25 # 私有属性
def get_temperature(self): # 公共读取接口
return self.__temperature
def set_temperature(self, temp): # 公共写入接口(带校验)
if -50 <= temp <= 150:
self.__temperature = temp
else:
raise ValueError("温度超出合理范围")
sensor = TemperatureSensor()
sensor.set_temperature(30)
print(sensor.get_temperature()) # 输出30
欢迎各位彦祖与热巴畅游本人专栏与技术博客
你的三连是我最大的动力
点击➡️指向的专栏名即可闪现
➡️渗透终极之红队攻击行动
➡️动画可视化数据结构与算法
➡️ 永恒之心蓝队联纵合横防御
➡️华为高级网络工程师
➡️华为高级防火墙防御集成部署
➡️ 未授权访问漏洞横向渗透利用
➡️逆向软件破解工程
➡️MYSQL REDIS 进阶实操
➡️红帽高级工程师
➡️红帽系统管理员
➡️HVV 全国各地面试题汇总