1. 类和对象基础
基本语法
class ClassName:
"""类的文档字符串"""
# 类属性
class_attribute = "类属性值"
def __init__(self, parameter1, parameter2):
"""构造方法"""
# 实例属性
self.instance_attr1 = parameter1
self.instance_attr2 = parameter2
self._protected_attr = "受保护的" # 约定上的保护
self.__private_attr = "私有的" # 名称修饰
def instance_method(self):
"""实例方法"""
return f"实例方法: {self.instance_attr1}"
@classmethod
def class_method(cls):
"""类方法"""
return f"类方法: {cls.class_attribute}"
@staticmethod
def static_method():
"""静态方法"""
return "静态方法"
创建和使用对象
# 创建对象
obj = ClassName("参数1", "参数2")
# 访问属性和方法
print(obj.instance_attr1)
print(obj.instance_method())
print(ClassName.class_method())
print(ClassName.static_method())
2. 封装 (Encapsulation)
访问控制
class BankAccount:
def __init__(self, account_holder, initial_balance=0):
self.account_holder = account_holder # 公开属性
self._account_number = self._generate_account_number() # 保护属性
self.__balance = initial_balance # 私有属性
def _generate_account_number(self):
"""保护方法(内部使用)"""
import random
return f"ACC{random.randint(100000, 999999)}"
def __validate_amount(self, amount):
"""私有方法"""
return amount > 0
# 公开接口
def deposit(self, amount):
if self.__validate_amount(amount):
self.__balance += amount
return True
return False
def withdraw(self, amount):
if self.__validate_amount(amount) and amount <= self.__balance:
self.__balance -= amount
return True
return False
def get_balance(self):
"""通过方法访问私有属性"""
return self.__balance
def get_account_info(self):
"""提供受保护信息的受控访问"""
return f"Holder: {self.account_holder}, Account: {self._account_number[-4:]}"
# 使用
account = BankAccount("Alice", 1000)
account.deposit(500)
print(account.get_balance()) # 1500
print(account.get_account_info())
# 强制访问(不推荐)
print(account._BankAccount__balance) # 名称修饰后的私有属性
属性装饰器
class Person:
def __init__(self, name, age):
self._name = name
self._age = age
@property
def name(self):
"""获取器"""
return self._name
@name.setter
def name(self, value):
"""设置器"""
if isinstance(value, str) and len(value) > 0:
self._name = value
else:
raise ValueError("姓名必须是非空字符串")
@property
def age(self):
return self._age
@age.setter
def age(self, value):
if 0 <= value <= 150:
self._age = value
else:
raise ValueError("年龄必须在0-150之间")
@property
def description(self):
"""只读属性"""
return f"{self._name}, {self._age}岁"
# 使用
person = Person("张三", 25)
person.name = "李四" # 调用setter
person.age = 30 # 调用setter
print(person.description) # 调用getter
3. 继承 (Inheritance)
基本继承
class Animal:
def __init__(self, name, species):
self.name = name
self.species = species
self._is_alive = True
def speak(self):
raise NotImplementedError("子类必须实现此方法")
def eat(self, food):
return f"{self.name} 正在吃 {food}"
def sleep(self):
return f"{self.name} 正在睡觉"
def __str__(self):
return f"{self.species}: {self.name}"
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name, "犬科") # 调用父类构造方法
self.breed = breed
def speak(self):
return "汪汪!"
def fetch(self, item):
return f"{self.name} 正在捡回 {item}"
class Cat(Animal):
def __init__(self, name, color):
super().__init__(name, "猫科")
self.color = color
def speak(self):
return "喵喵!"
def climb(self, height):
return f"{self.name} 爬到了 {height}米高"
# 使用继承
dog = Dog("旺财", "金毛")
cat = Cat("咪咪", "白色")
print(dog.speak()) # 汪汪!
print(cat.speak()) # 喵喵!
print(dog.eat("狗粮")) # 继承的方法
print(cat.climb(2)) # 特有的方法
多重继承
class Flyable:
def __init__(self, max_altitude=1000):
self.max_altitude = max_altitude
self._is_flying = False
def take_off(self):
self._is_flying = True
return "起飞"
def land(self):
self._is_flying = False
return "降落"
def fly(self):
if self._is_flying:
return "正在飞行"
return "尚未起飞"
class Swimmable:
def __init__(self, max_depth=10):
self.max_depth = max_depth
self._is_swimming = False
def dive(self):
self._is_swimming = True
return "下潜"
def surface(self):
self._is_swimming = False
return "浮出水面"
def swim(self):
if self._is_swimming:
return "正在游泳"
return "不在水中"
class Duck(Animal, Flyable, Swimmable):
def __init__(self, name):
Animal.__init__(self, name, "鸭科")
Flyable.__init__(self, 500) # 鸭子飞不高
Swimmable.__init__(self, 3) # 鸭子潜不深
def speak(self):
return "嘎嘎!"
def act(self):
actions = [
self.speak(),
self.eat("虫子"),
self.take_off(),
self.fly(),
self.land(),
self.dive(),
self.swim(),
self.surface()
]
return " | ".join(actions)
# 使用多重继承
duck = Duck("唐老鸭")
print(duck.act())
# 方法解析顺序 (MRO)
print(Duck.__mro__)
# (<class '__main__.Duck'>, <class '__main__.Animal'>,
# <class '__main__.Flyable'>, <class '__main__.Swimmable'>, <class 'object'>)
4. 多态 (Polymorphism)
方法重写
class Shape:
def __init__(self, name):
self.name = name
def area(self):
"""计算面积 - 抽象方法"""
raise NotImplementedError("子类必须实现area方法")
def perimeter(self):
"""计算周长 - 抽象方法"""
raise NotImplementedError("子类必须实现perimeter方法")
def __str__(self):
return f"{self.name} - 面积: {self.area():.2f}, 周长: {self.perimeter():.2f}"
class Rectangle(Shape):
def __init__(self, width, height):
super().__init__("矩形")
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):
super().__init__("圆形")
self.radius = radius
def area(self):
import math
return math.pi * self.radius ** 2
def perimeter(self):
import math
return 2 * math.pi * self.radius
class Triangle(Shape):
def __init__(self, a, b, c):
super().__init__("三角形")
self.a = a
self.b = b
self.c = c
def area(self):
# 使用海伦公式
s = self.perimeter() / 2
return (s * (s - self.a) * (s - self.b) * (s - self.c)) ** 0.5
def perimeter(self):
return self.a + self.b + self.c
# 多态演示
def process_shapes(shapes):
"""处理各种形状 - 多态的体现"""
total_area = 0
total_perimeter = 0
for shape in shapes:
print(shape) # 调用各自的 __str__ 方法
total_area += shape.area() # 动态调用各自的area方法
total_perimeter += shape.perimeter() # 动态调用各自的perimeter方法
print(f"总面积: {total_area:.2f}")
print(f"总周长: {total_perimeter:.2f}")
# 创建不同形状的对象
shapes = [
Rectangle(5, 3),
Circle(4),
Triangle(3, 4, 5)
]
process_shapes(shapes)
鸭子类型 (Duck Typing)
class FileReader:
def read(self):
return "从文件读取数据"
class DatabaseReader:
def read(self):
return "从数据库读取数据"
class APIReader:
def read(self):
return "从API读取数据"
def read_data(reader):
"""不关心reader的具体类型,只要它有read方法"""
return reader.read()
# 使用不同的reader
readers = [FileReader(), DatabaseReader(), APIReader()]
for reader in readers:
print(read_data(reader)) # 多态的体现
5. 高级特性
抽象基类
from abc import ABC, abstractmethod
class Vehicle(ABC):
def __init__(self, brand, model):
self.brand = brand
self.model = model
self._is_running = False
@abstractmethod
def start_engine(self):
pass
@abstractmethod
def stop_engine(self):
pass
def get_info(self):
return f"{self.brand} {self.model}"
class Car(Vehicle):
def start_engine(self):
self._is_running = True
return "汽车引擎启动"
def stop_engine(self):
self._is_running = False
return "汽车引擎停止"
class Motorcycle(Vehicle):
def start_engine(self):
self._is_running = True
return "摩托车引擎启动"
def stop_engine(self):
self._is_running = False
return "摩托车引擎停止"
# 不能实例化抽象类
# vehicle = Vehicle("通用", "型号") # 报错
car = Car("丰田", "卡罗拉")
motorcycle = Motorcycle("本田", "CBR")
魔术方法
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
"""+ 运算符重载"""
return Vector(self.x + other.x, self.y + other.y)
def __sub__(self, other):
"""- 运算符重载"""
return Vector(self.x - other.x, self.y - other.y)
def __mul__(self, scalar):
"""* 运算符重载"""
return Vector(self.x * scalar, self.y * scalar)
def __str__(self):
"""字符串表示"""
return f"Vector({self.x}, {self.y})"
def __repr__(self):
"""解释器表示"""
return f"Vector({self.x}, {self.y})"
def __len__(self):
"""长度(模)"""
return int((self.x**2 + self.y**2)**0.5)
def __eq__(self, other):
"""== 运算符重载"""
return self.x == other.x and self.y == other.y
def __getitem__(self, index):
"""索引访问"""
if index == 0:
return self.x
elif index == 1:
return self.y
else:
raise IndexError("Vector索引超出范围")
# 使用魔术方法
v1 = Vector(2, 3)
v2 = Vector(1, 4)
print(v1 + v2) # Vector(3, 7)
print(v1 * 2) # Vector(4, 6)
print(len(v1)) # 3
print(v1 == v2) # False
print(v1[0]) # 2
6. 设计原则
组合优于继承
class Engine:
def start(self):
return "引擎启动"
def stop(self):
return "引擎停止"
class Wheels:
def __init__(self, count):
self.count = count
def rotate(self):
return f"{self.count}个轮子在旋转"
class Car:
def __init__(self, brand, wheel_count=4):
self.brand = brand
self.engine = Engine() # 组合
self.wheels = Wheels(wheel_count) # 组合
def drive(self):
return f"{self.brand}: {self.engine.start()} -> {self.wheels.rotate()}"
# 使用组合
car = Car("宝马")
print(car.drive())