面向对象编程(OOP)是 Python 中最重要的编程范式之一,它将数据和操作数据的方法封装在一起,提高了代码的复用性和可维护性。本文将结合实际代码示例,详细讲解 Python 面向对象编程的核心概念和常用技巧。
一、类与对象的基本概念
1.1 面向过程与面向对象的区别
- 面向过程:像 "蛋炒饭",步骤紧密耦合,一步接着一步执行(如打开冰箱→放入大象→关闭冰箱)
- 面向对象:像 "盖浇饭",将功能封装成独立组件(如冰箱类负责开关,大象类负责进出)
1.2 类与对象的定义
- 类:是对象的抽象模板,包含一类事物的共有特征(属性)和行为(方法)
- 对象:是类的实例化,是具体的事物
# 定义Student类
class Student:
# 构造方法:创建对象时自动执行,初始化实例属性
def __init__(self, name, age):
self.name = name # 实例属性
self.age = age # 实例属性
# 实例方法:定义对象的行为
def show_info(self):
print(self.name, self.age)
# 创建对象(实例化)
zs = Student('张三', 20)
ls = Student('李四', 22)
# 访问属性和方法
print(zs.name) # 输出:张三
zs.show_info() # 输出:张三 20
提示:self
代表当前对象,谁调用方法就指代谁
二、类属性与实例属性
属性分为两种:类属性和实例属性,它们的作用域和访问方式有所不同。
import math
class Circle:
PI = math.pi # 类属性:属于类,所有对象共享
def __init__(self, r):
self.r = r # 实例属性:每个对象独有的属性
# 访问类属性
print(Circle.PI) # 方式1:类名.属性名,输出:3.14159...
c1 = Circle(2)
print(c1.PI) # 方式2:对象名.属性名(不推荐,建议用类名访问)
# 访问实例属性
print(c1.r) # 只能通过对象访问,输出:2
区别总结:
- 类属性:所有对象共享,定义在类中、方法外
- 实例属性:每个对象独有,定义在
__init__
方法中 - 类属性推荐用
类名.属性名
访问,实例属性用对象名.属性名
访问
三、三大方法类型:实例方法、类方法、静态方法
3.1 实例方法
- 第一个参数必须是
self
(指代当前对象) - 可访问实例属性和类属性
- 通过
对象名.方法名()
调用
def show(self): # 实例方法
print(f"实例属性:{self.n},类属性:{self.count}")
3.2 类方法
- 用
@classmethod
装饰器标识 - 第一个参数必须是
cls
(指代当前类) - 主要用于操作类属性,不能直接访问实例属性
- 通过
类名.方法名()
调用
@classmethod
def set_count(cls): # 类方法
cls.count += 1 # 操作类属性
3.3 静态方法
- 用
@staticmethod
装饰器标识 - 没有默认参数(不需要
self
或cls
) - 不能直接访问实例属性,可通过
类名.类属性
访问类属性 - 更像独立的工具函数,与类和对象关联较弱
- 通过
类名.方法名()
调用
@staticmethod
def check_str(s): # 静态方法
return s == s[::-1] # 判断回文串
四、对象的字符串表示
当我们打印对象时,默认显示的是内存地址,通过__str__
和__repr__
可以自定义对象的字符串形式。
import json
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
# 用于print输出,更友好的字符串
return json.dumps(self.__dict__, ensure_ascii=False)
def __repr__(self):
# 用于解释器显示(如在列表中),通常与__str__保持一致
return self.__str__()
zs = Student('张三', 20)
print(zs) # 输出:{"name": "张三", "age": 20}
print([zs]) # 输出:[{"name": "张三", "age": 20}](因__repr__生效)
区别:
__str__
:面向用户,侧重可读性__repr__
:面向开发者,侧重准确性(调试用)
五、类的魔术方法
Python 中以__
开头和结尾的方法称为魔术方法,它们在特定场景下自动调用。
5.1 构造与初始化
__new__
:创建对象(先执行)__init__
:初始化对象属性(后执行)
class Student:
def __new__(cls, *args, **kwargs):
print('创建对象...')
return super().__new__(cls) # 必须返回创建的对象
def __init__(self, name, age):
print('初始化属性...')
self.name = name
self.age = age
5.2 运算符重载
通过魔术方法可以自定义对象的运算符行为:
class Student:
def __init__(self, age):
self.age = age
def __add__(self, other): # 定义+运算
return self.age + other.age
def __gt__(self, other): # 定义>运算
return self.age > other.age
zs = Student(20)
ls = Student(30)
print(zs + ls) # 输出:50(调用__add__)
print(zs > ls) # 输出:False(调用__gt__)
常用运算符魔术方法:
- 算术:
__add__
(+)、__sub__
(-)、__mul__
(*)、__truediv__
(/) - 比较:
__gt__
(>)、__lt__
(<)、__eq__
(==)、__ne__
(!=)
六、获取类与对象的信息
在开发和调试中,我们常需要查看类和对象的信息,常用方法如下:
class Student:
"""学生类"""
def __init__(self, name, age):
self.name = name
self.age = age
zs = Student('张三', 20)
# 查看对象属性字典
print(zs.__dict__) # 输出:{'name': '张三', 'age': 20}
# 查看对象/类的所有成员
print(dir(zs)) # 对象的所有属性和方法
print(dir(Student)) # 类的所有成员
# 类的元信息
print(Student.__name__) # 类名:Student
print(Student.__doc__) # 类文档:学生类
print(Student.__base__) # 父类:<class 'object'>
七、实战案例:商品库存管理
下面通过一个商品管理类,综合应用上述知识:
class Product:
def __init__(self, name, stock):
self.name = name # 商品名称
self.stock = stock # 库存
def add_stock(self, quantity):
"""增加库存"""
self.stock += quantity
def reduce_stock(self, quantity):
"""减少库存,库存不足时提示"""
if quantity > self.stock:
print("库存不足")
else:
self.stock -= quantity
def display_stock(self):
"""显示当前库存"""
return self.stock
# 使用示例
p = Product('笔', 50)
p.add_stock(10)
print(p.display_stock()) # 输出:60
p.reduce_stock(12)
print(p.display_stock()) # 输出:48
总结
面向对象编程是 Python 开发的核心技能,本文介绍了类与对象、属性与方法、魔术方法等关键知识点。掌握这些概念后,你可以编写出更模块化、更易维护的代码。记住,多练习是掌握面向对象编程的关键,尝试将这些知识应用到实际项目中吧!