引言
面向对象编程(OOP)是Python的核心范式之一。相比于面向过程的"堆叠代码",OOP强调设计 ------通过"类"和"实例"的交互来构建程序。本篇将从基础概念出发,结合你的实际代码,深入讲解类的定义、__init__初始化方法、实例属性封装,并完成一个有趣的"随机点连线"小项目。
1. 类与实例:从int说起
在Python中,一切皆对象。我们常用的整数10,实际上就是int类的实例。
a = int(10) # 等价于 a = 10 print(a, type(a)) # 10 <class 'int'>
自定义类使用class关键字:
class Person: """人类:类型""" pass p1 = Person() # 创建Person类的实例 print(p1, type(p1)) # <__main__.Person object at 0x...> <class '__main__.Person'>
每个实例在内存中都有独立的地址,它们共享类定义的属性和方法。
2. 初始化方法 __init__:给实例"赋初值"
__init__是Python的魔法方法,在实例化时自动调用,用于初始化实例属性。你的代码演示了这一点:
class Person: def __init__(self, name, age): print("初始化函数执行了", id(self)) self.name = name # 绑定属性 self.age = age p1 = Person("马云", 25) print(id(p1), p1.name, p1.age) # 输出内存地址和属性值
-
self代表当前实例,它和类外部的实例名(如p1)指向同一块内存(id(self) == id(p1))。 -
通过
self.属性名 = 值,我们将外部传入的数据绑定到实例上,实现"个性化"。
3. 封装:通过方法访问和修改私有数据
封装是OOP的三大特性之一,将数据(属性)和操作(方法)包装在一起。你的Person类提供了get/set方法,便于控制访问:
def get_name(self): return self.name def set_name(self, name): self.name = name
这样做的好处是可以在set方法中添加校验逻辑(例如年龄不能为负),而外部调用者无需关心内部实现。
4. 实战练习:随机点距离计算与可视化
你在代码中定义了一个Point类,并利用turtle绘制多个随机点之间的连线。这是一个很好的封装练习。
Point类:
class Point: def __init__(self, x, y): self.x = x self.y = y def get_x(self): return self.x def get_y(self): return self.y
计算两点距离(欧氏距离):
import random p1 = Point(10, 20) p2 = Point(30, 40) distance = ((p1.get_x() - p2.get_x())**2 + (p1.get_y() - p2.get_y())**2) ** 0.5 print(distance) # 28.284...
可视化绘制 :
Draw类接收一个Point列表,并在海龟画布上绘制所有点之间的连线(组合数C(n,2))。
class Draw: def __init__(self, points): self.points = points def draw_between_points(self): turtle.up() for i in range(len(self.points)): for j in range(i+1, len(self.points)): turtle.goto(self.points[i].get_x(), self.points[i].get_y()) turtle.down() turtle.goto(self.points[j].get_x(), self.points[j].get_y()) turtle.up() turtle.mainloop() # 生成3个随机点并绘制 points = [Point(random.randint(-200,200), random.randint(-200,200)) for _ in range(3)] draw = Draw(points) draw.draw_between_points()
运行后,你会看到海龟依次连接所有点对,形成三角形(3个点)或其他多边形(更多点)。
5. 总结
-
类 是模板,实例是具体的对象。
-
__init__用于初始化实例属性,self代表当前实例。 -
封装通过方法暴露属性,提高代码的可维护性和安全性。
-
动手实践(如随机点连线)能加深对OOP的理解。