


























面向对象编程是一种程序设计范式,它将数据(属性)和操作(方法)封装在“对象”中。Python 从设计之初就是一门面向对象的语言,在 Python 3 中,OOP 的语法和特性更加完善和一致。下面系统性地介绍 Python 3 中 OOP 的核心概念和用法。
类(Class) 是创建对象的蓝图,对象(Object) 是类的实例。
class Dog:
# 类属性(所有实例共享)
species = "Canis familiaris"
# 初始化方法(构造器)
def __init__(self, name, age):
self.name = name # 实例属性
self.age = age
# 实例方法
def bark(self):
return f"{self.name} says woof!"
# 创建对象
my_dog = Dog("Buddy", 3)
print(my_dog.bark()) # Buddy says woof!
print(my_dog.species) # Canis familiaris
__init__ 是特殊方法,在对象创建时自动调用,用于设置初始状态。self 指向当前实例,必须作为实例方法的第一个参数。继承允许子类复用父类的属性和方法,并可以扩展或重写。
单继承:
class Puppy(Dog):
def __init__(self, name, age, training_level):
super().__init__(name, age) # 调用父类初始化
self.training_level = training_level
def bark(self): # 重写父类方法
return f"{self.name} says yip!"
p = Puppy("Max", 1, "beginner")
print(p.bark()) # Max says yip!
多重继承:Python 支持多重继承,方法解析顺序(MRO)遵循 C3 线性化算法,可通过 类.__mro__ 查看。
class Flyer:
def fly(self):
print("Flying")
class Swimmer:
def swim(self):
print("Swimming")
class Duck(Flyer, Swimmer):
pass
d = Duck()
d.fly() # Flying
d.swim() # Swimming
super():在 Python 3 中,super() 可以不传参数,自动在 MRO 中查找下一个类,推荐使用。
Python 没有严格的私有关键字,通过命名约定实现“保护”和“私有”:
_single_leading_underscore:约定为“保护”属性,不应直接访问(但解释器不强制)。__double_leading_underscore:名称修饰(name mangling),在类内部会变形为 _ClassName__attr,防止子类意外覆盖。class BankAccount:
def __init__(self, owner, balance):
self.owner = owner
self.__balance = balance # 私有属性
def deposit(self, amount):
self.__balance += amount
def get_balance(self): # 通过方法访问
return self.__balance
acc = BankAccount("Alice", 1000)
# print(acc.__balance) # AttributeError
print(acc._BankAccount__balance) # 1000(但不应这样用)
@property)@property 将方法转换为属性调用,实现更优雅的 getter/setter,同时可以添加验证逻辑。
class Temperature:
def __init__(self, celsius):
self._celsius = celsius
@property
def celsius(self):
return self._celsius
@celsius.setter
def celsius(self, value):
if value < -273.15:
raise ValueError("Temperature below absolute zero!")
self._celsius = value
@property
def fahrenheit(self):
return self._celsius * 9/5 + 32
t = Temperature(25)
print(t.celsius) # 25
t.celsius = 30 # 调用 setter
print(t.fahrenheit) # 86.0
多态指不同对象对同一消息作出不同响应。Python 通过“鸭子类型”实现:只要对象具有所需的方法或属性,就可以被使用,而不在乎其具体类型。
class Cat:
def speak(self):
return "Meow"
class Dog:
def speak(self):
return "Woof"
def animal_sound(animal):
print(animal.speak())
animal_sound(Cat()) # Meow
animal_sound(Dog()) # Woof
特殊方法(以双下划线开头和结尾)使自定义类能融入 Python 的内置行为。
常用特殊方法:
| 方法 | 用途 |
|---|---|
__init__(self, ...) |
初始化对象 |
__str__(self) |
用于 print() 和 str() |
__repr__(self) |
用于交互式环境和 repr(),应尽量准确可重建 |
__len__(self) |
用于 len() |
__getitem__(self, key) |
实现索引访问 |
__add__(self, other) |
实现 + 运算符 |
__call__(self, ...) |
使对象可被调用 |
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 __repr__(self):
return f"Vector({self.x}, {self.y})"
v1 = Vector(1, 2)
v2 = Vector(3, 4)
v3 = v1 + v2
print(v3) # Vector(4, 6)
@classmethod:方法接收类本身(cls)作为第一个参数,通常用于工厂方法。@staticmethod:不接收隐式的第一个参数,行为类似普通函数,但放在类中便于组织。class Person:
population = 0
def __init__(self, name):
self.name = name
Person.population += 1
@classmethod
def from_birth_year(cls, name, birth_year):
age = 2026 - birth_year # 假设当前年份
return cls(name, age) # 实际上需要调整 __init__,演示用
@staticmethod
def is_adult(age):
return age >= 18
p = Person.from_birth_year("Bob", 2000)
print(Person.is_adult(20)) # True
抽象基类用于定义接口,强制子类实现某些方法。使用 abc 模块。
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)
# s = Shape() # TypeError: Can't instantiate abstract class Shape
r = Rectangle(3, 4)
print(r.area()) # 12
dataclasses)Python 3.7 引入 dataclasses,自动生成 __init__、__repr__、__eq__ 等常用方法,减少样板代码。
from dataclasses import dataclass
@dataclass
class Point:
x: float
y: float
label: str = "origin" # 默认值
def distance_from(self, other):
return ((self.x - other.x)**2 + (self.y - other.y)**2)**0.5
p1 = Point(1, 2)
p2 = Point(4, 6)
print(p1) # Point(x=1, y=2, label='origin')
print(p1.distance_from(p2)) # 5.0
dataclass 还支持 frozen=True(不可变)、order=True(比较排序)等参数。
虽然 Python 是动态类型,但支持类型提示(PEP 484),结合 typing 模块可以提高代码可读性和工具支持。
from typing import List
class ShoppingCart:
def __init__(self, items: List[str]) -> None:
self.items = items
def add_item(self, item: str) -> None:
self.items.append(item)
def get_items(self) -> List[str]:
return self.items
类型提示不影响运行时行为,但配合静态检查工具(如 mypy)能发现类型错误。
super() 不再需要参数,更简洁。class MyClass(metaclass=MyMeta) 替代 __metaclass__ 属性。dataclasses 和 @dataclass。typing 引入。object(新式类统一)。Python 3 中的 OOP 设计既直观又强大。它融合了经典的类机制、灵活的多重继承、强大的特殊方法以及现代的语法糖(如数据类和属性装饰器)。理解这些概念能帮助你编写出结构清晰、可扩展的代码。在实践中,根据项目需求选择合适的 OOP 风格——从简单的类到完整的抽象接口,Python 都提供了完备的支持。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。