面向对象编程(OOP)把数据和操作数据的方法打包成"对象",让代码更贴近现实世界的建模方式。Python 的类机制灵活而简洁:没有繁琐的访问修饰符,用约定和装饰器实现封装。本文从类与对象讲到继承、多态和魔法方法。
1. 类与对象
类(class)是蓝图,对象(instance)是根据蓝图造出来的实例。先定义一个最简单的类:
class Dog:
"""狗类:定义了狗应有的数据和行为"""
species = "犬科"
def __init__(self, name, age):
self.name = name
self.age = age
def bark(self):
return f"{self.name} 汪汪叫!"
d1 = Dog("旺财", 3)
d2 = Dog("来福", 5)
print(d1.bark())
print(d1.species)
print(d1.age, d2.age)
2. __init__ 与 self
__init__ 是构造方法,实例创建时自动调用;self 指代实例本身,是实例方法的第一个参数。
class Student:
def __init__(self, name, scores):
self.name = name
self.scores = scores # 列表
def average(self):
return sum(self.scores) / len(self.scores)
s = Student("Ada", [92, 88, 95])
print(f"{s.name} 平均分 {s.average():.1f}")
3. 实例方法、类方法与静态方法
三种方法的区别在于第一个参数:实例方法收 self,类方法收 cls,静态方法什么特殊参数都不收:
class Circle:
pi = 3.14159
def __init__(self, radius):
self.radius = radius
def area(self):
return self.pi * self.radius ** 2
@classmethod
def from_diameter(cls, d):
return cls(d / 2)
@staticmethod
def is_valid(r):
return r > 0
c = Circle.from_diameter(10)
print(c.area())
print(Circle.is_valid(3))
4. 继承与多态
子类继承父类并可覆写方法;多态让不同子类用同一接口表现出不同行为:
class Animal:
def speak(self):
return "..."
class Cat(Animal):
def speak(self):
return "喵喵喵"
class Dog(Animal):
def speak(self):
return "汪汪汪"
for a in [Cat(), Dog(), Animal()]:
print(a.speak())
子类里还能用 super() 调用父类方法,实现"先扩展再覆写"的常见模式。
5. 封装:property 与私有约定
Python 用下划线约定表达私有(_x 约定私有,__x 会被名字改写),对外暴露只读属性用 @property:
class BankAccount:
def __init__(self, owner):
self.owner = owner
self._balance = 0
@property
def balance(self): # 只读访问器
return self._balance
def deposit(self, amount):
if amount > 0:
self._balance += amount
else:
raise ValueError("金额必须为正")
acc = BankAccount("Ada")
acc.deposit(100)
print(acc.balance)
6. 魔法方法:__str__ 与 __repr__
双下划线方法是 Python 在特定时机自动调用的"魔法方法":print 时用 __str__,调试时用 __repr__:
class Point:
def __init__(self, x, y):
self.x, self.y = x, y
def __str__(self):
return f"({self.x}, {self.y})" # 给人看
def __repr__(self):
return f"Point(x={self.x}, y={self.y})" # 给开发者看
p = Point(3, 4)
print(p) # (3, 4) 调用 __str__
print(repr(p)) # Point(x=3, y=4) 调用 __repr__
💡 学习建议:试着写一个TodoList类,支持 add/done/remaining 方法,再实现__len__和__str__。一个能跑的小类,胜过背十页概念。