1. 类和对象
1-1. 类定义
在 Python
中,类通过 class
关键字定义。类名通常使用大写字母开头。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
TIP
__init__
方法是一个特殊的构造方法,用于初始化对象的属性。
1-2. 对象创建
person = Person("John", 25)
print(person.name) # 输出: John
print(person.age) # 输出: 25
1-3. 继承
在 Python
中,继承通过在类定义时指定父类来实现。
class Student(Person):
def __init__(self, name, age, student_id):
super().__init__(name, age)
self.student_id = student_id
TIP
super()
函数用于调用父类的方法。
1-4. 多态
多态是指同一个方法在不同的子类中具有不同的实现。
class Animal:
def speak(self):
pass
class Dog(Animal):
def speak(self):
return "Woof"
animal = Animal()
dog = Dog()
print(animal.speak()) # 输出: None
print(dog.speak()) # 输出: Woof
TIP
多态使得代码更加灵活和可扩展。
1-5. 封装
封装是将数据和操作数据的方法绑定在一起,隐藏对象的内部实现细节。
class BankAccount:
def __init__(self, owner, balance=0):
self.owner = owner
self.__balance = balance # 私有属性
def deposit(self, amount):
self.__balance += amount
def get_balance(self):
return self.__balance
TIP
私有属性不能直接访问,需要通过类提供的方法来访问。
1-6. 抽象类和接口
- 抽象类
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
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)
- 接口(Protocol)
from typing import Protocol
class Drawable(Protocol):
def draw(self) -> str:
...
class Circle:
def draw(self) -> str:
return "绘制圆形"
class Square:
def draw(self) -> str:
return "绘制方形"
1-7. 多重继承
class A:
def method_a(self):
return "A"
class B:
def method_b(self):
return "B"
class C(A, B):
def method_c(self):
return "C"
c = C()
print(c.method_a()) # A
print(c.method_b()) # B
print(c.method_c()) # C
TIP
多重继承可能导致菱形继承问题,需要注意方法解析顺序(MRO)。
1-8. 组合和聚合
- 组合
class Engine:
def start(self):
return "引擎启动"
class Car:
def __init__(self):
self.engine = Engine() # 组合关系
def start(self):
return self.engine.start()
car = Car()
print(car.start()) # 引擎启动
- 聚合
class Department:
def __init__(self, name):
self.name = name
self.employees = [] # 聚合关系
def add_employee(self, employee):
self.employees.append(employee)
class Employee:
def __init__(self, name):
self.name = name
dept = Department("技术部")
emp1 = Employee("张三")
emp2 = Employee("李四")
dept.add_employee(emp1)
dept.add_employee(emp2)
2. 魔术方法
魔术方法(Magic Methods)是 Python
中的一些特殊方法,它们在类中定义,用于实现一些特殊的行为。以下是一些常用的魔术方法:
2-1. __str__
__str__
方法用于定义对象的 str
方法。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"Person(name={self.name}, age={self.age})"
person = Person("John", 25)
print(person) # 输出: Person(name=John, age=25)
2-2. __repr__
__repr__
方法用于定义对象的 repr
方法。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f"Person(name={self.name}, age={self.age})"
person = Person("John", 25)
print(repr(person)) # 输出: Person(name=John, age=25)
2-3. __len__
__len__
方法用于定义对象的 len
方法。
class MyList:
def __init__(self, items):
self.items = items
def __len__(self):
return len(self.items)
my_list = MyList([1, 2, 3, 4, 5])
print(len(my_list)) # 输出: 5
2-4. __getitem__
__getitem__
方法用于定义对象的 getitem
方法。
class MyList:
def __init__(self, items):
self.items = items
def __getitem__(self, index):
return self.items[index]
my_list = MyList([1, 2, 3, 4, 5])
print(my_list[0]) # 输出: 1
2-5. __setitem__
__setitem__
方法用于定义对象的 setitem
方法。
class MyList:
def __init__(self, items):
self.items = items
def __setitem__(self, index, value):
self.items[index] = value
my_list = MyList([1, 2, 3, 4, 5])
my_list[0] = 10 # 输出: [10, 2, 3, 4, 5]
2-6. __delitem__
__delitem__
方法用于定义对象的 delitem
方法。
class MyList:
def __init__(self, items):
self.items = items
def __delitem__(self, index):
del self.items[index]
my_list = MyList([1, 2, 3, 4, 5])
del my_list[0] # 输出: [2, 3, 4, 5]
2-7. __call__
__call__
方法用于定义对象的 call
方法。
class MyClass:
def __call__(self, *args, **kwargs):
return "Hello, World!"
my_class = MyClass()
print(my_class()) # 输出: Hello, World!
2-8. __iter__
__iter__
方法用于定义对象的 iter
方法。
class MyIterable:
def __iter__(self):
return iter([1, 2, 3])
my_iterable = MyIterable()
for item in my_iterable:
print(item) # 输出: 1 2 3
2-9. __next__
__next__
方法用于定义对象的 next
方法。
class MyIterator:
def __init__(self, data):
self.data = data
self.index = 0
def __next__(self):
if self.index < len(self.data):
result = self.data[self.index]
self.index += 1
return result
else:
raise StopIteration
my_iterator = MyIterator([1, 2, 3])
print(next(my_iterator)) # 输出: 1
2-10. __contains__
__contains__
方法用于定义对象的 contains
方法。
class MyContainer:
def __contains__(self, item):
return item in [1, 2, 3]
print(2 in my_container) # 输出: True
2-11. __getattr__
__getattr__
方法用于定义对象的 getattr
方法。
class MyClass:
def __getattr__(self, name):
return f"Attribute '{name}' not found"
my_class = MyClass()
print(my_class.name) # 输出: Attribute 'name' not found
2-12. __setattr__
__setattr__
方法用于定义对象的 setattr
方法。
class MyClass:
def __setattr__(self, name, value):
self.__dict__[name] = value
my_class = MyClass()
my_class.name = "John"
print(my_class.name) # 输出: John
2-13. __getattribute__
__getattribute__
方法用于定义对象的 getattribute
方法。
class MyClass:
def __getattribute__(self, name):
return f"Attribute '{name}' not found"
my_class = MyClass()
print(my_class.name) # 输出: Attribute 'name' not found
2-14. __setattribute__
__setattribute__
方法用于定义对象的 setattribute
方法。
class MyClass:
def __setattribute__(self, name, value):
self.__dict__[name] = value
my_class = MyClass()
my_class.name = "John"
print(my_class.name) # 输出: John
2-15. __delattr__
__delattr__
方法用于定义对象的 delattr
方法。
class MyClass:
def __delattr__(self, name):
del self.__dict__[name]
my_class = MyClass()
my_class.name = "John"
del my_class.name # 输出: Attribute 'name' not found
3. 属性装饰器
3-1. @property
装饰器
@property
装饰器用于将方法转换为只读属性,它有以下主要用途:
- 数据验证和转换
class Person:
def __init__(self, age):
self._age = age
@property
def age(self):
return self._age
@age.setter
def age(self, value):
if not isinstance(value, int):
raise TypeError("年龄必须是整数")
if value < 0 or value > 150:
raise ValueError("年龄必须在0-150之间")
self._age = value
person = Person(25)
print(person.age) # 25
person.age = 30 # 正常赋值
person.age = -1 # 抛出 ValueError
- 计算属性
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
@property
def area(self):
return self.width * self.height
@property
def perimeter(self):
return 2 * (self.width + self.height)
rect = Rectangle(5, 3)
print(rect.area) # 15
print(rect.perimeter) # 16
- 只读属性
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius
@property
def diameter(self):
return self._radius * 2
circle = Circle(5)
print(circle.radius) # 5
print(circle.diameter) # 10
# circle.radius = 10 # 错误:只读属性
3-2. 类属性的其他定义方式
- 类变量
class Student:
# 类变量,所有实例共享
school = "Python大学"
def __init__(self, name):
# 实例变量
self.name = name
student1 = Student("张三")
student2 = Student("李四")
print(student1.school) # Python大学
print(student2.school) # Python大学
Student.school = "新Python大学" # 修改类变量
print(student1.school) # 新Python大学
- 描述符(Descriptor)
class Age:
def __get__(self, instance, owner):
return instance._age
def __set__(self, instance, value):
if not isinstance(value, int):
raise TypeError("年龄必须是整数")
if value < 0 or value > 150:
raise ValueError("年龄必须在0-150之间")
instance._age = value
class Person:
age = Age() # 使用描述符
def __init__(self, age):
self._age = age
person = Person(25)
print(person.age) # 25
person.age = 30 # 正常赋值
# person.age = -1 # 抛出 ValueError
__slots__
类属性
class Point:
__slots__ = ['x', 'y'] # 限制实例只能有 x 和 y 属性
def __init__(self, x, y):
self.x = x
self.y = y
point = Point(1, 2)
# point.z = 3 # 错误:无法添加新属性
__dict__
和动态属性
class DynamicClass:
def __init__(self):
self.__dict__['dynamic_attr'] = 'value'
def __getattr__(self, name):
if name == 'missing_attr':
return '动态属性值'
raise AttributeError(f"属性 {name} 不存在")
def __setattr__(self, name, value):
if name.startswith('_'):
raise AttributeError("不能设置以下划线开头的属性")
super().__setattr__(name, value)
obj = DynamicClass()
print(obj.dynamic_attr) # value
print(obj.missing_attr) # 动态属性值
# obj._private = 1 # 错误:不能设置以下划线开头的属性
- 元类(Metaclass)定义类属性
class Meta(type):
def __new__(cls, name, bases, attrs):
# 添加类属性
attrs['version'] = '1.0'
attrs['author'] = 'Python'
return super().__new__(cls, name, bases, attrs)
class MyClass(metaclass=Meta):
pass
print(MyClass.version) # 1.0
print(MyClass.author) # Python
3-3. 属性访问控制
- 私有属性
class BankAccount:
def __init__(self, balance):
self.__balance = balance # 私有属性
def get_balance(self):
return self.__balance
def set_balance(self, value):
if value >= 0:
self.__balance = value
account = BankAccount(1000)
print(account.get_balance()) # 1000
# print(account.__balance) # 错误:无法直接访问私有属性
- 保护属性
class Parent:
def __init__(self):
self._protected = "受保护的属性" # 保护属性
class Child(Parent):
def access_protected(self):
return self._protected # 子类可以访问
child = Child()
print(child.access_protected()) # 受保护的属性
# print(child._protected) # 可以访问,但不推荐
3-4. 属性装饰器的使用场景
数据验证和转换
- 输入验证
- 数据格式转换
- 范围检查
计算属性
- 基于其他属性计算
- 缓存计算结果
- 延迟计算
只读属性
- 防止属性被修改
- 封装内部实现
- 提供只读接口
属性依赖
- 属性之间的关联
- 自动更新相关属性
- 维护数据一致性
接口兼容
- 保持向后兼容
- 重构内部实现
- 提供统一接口
4. 类装饰器
4-1. 类方法装饰器
class MyClass:
@classmethod
def create(cls, value):
return cls(value)
def __init__(self, value):
self.value = value
obj = MyClass.create(10)
print(obj.value) # 10
4-2. 静态方法装饰器
class Math:
@staticmethod
def add(x, y):
return x + y
@staticmethod
def multiply(x, y):
return x * y
print(Math.add(5, 3)) # 8
print(Math.multiply(5, 3)) # 15
4-3. 抽象方法装饰器
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
5. 设计模式
5-1. 单例模式
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
s1 = Singleton()
s2 = Singleton()
print(s1 is s2) # True
5-2. 工厂模式
class Animal:
def speak(self):
pass
class Dog(Animal):
def speak(self):
return "Woof"
class Cat(Animal):
def speak(self):
return "Meow"
class AnimalFactory:
@staticmethod
def create_animal(animal_type):
if animal_type == "dog":
return Dog()
elif animal_type == "cat":
return Cat()
else:
raise ValueError("未知的动物类型")
dog = AnimalFactory.create_animal("dog")
cat = AnimalFactory.create_animal("cat")
print(dog.speak()) # Woof
print(cat.speak()) # Meow
5-3. 观察者模式
class Subject:
def __init__(self):
self.observers = []
def attach(self, observer):
self.observers.append(observer)
def notify(self):
for observer in self.observers:
observer.update()
class Observer:
def update(self):
pass
class ConcreteObserver(Observer):
def update(self):
print("收到通知")
subject = Subject()
observer = ConcreteObserver()
subject.attach(observer)
subject.notify() # 收到通知