python学习笔记 | 11.1、面向对象高级编程-使用__slots__
2026/5/24 1:39:10 网站建设 项目流程

一、先懂前置知识:Python 动态绑定特点

1. 核心思路

Python 是动态语言,类定义好之后,运行时可以随便给实例加属性、加方法,不用提前在类里写好。

2. 实例演示

# 1. 空类 class Student: pass # 2. 给单个实例动态加属性 s1 = Student() s1.name = "小明" print(s1.name) # 小明 # 3. 单个实例绑定方法 from types import MethodType def set_age(self,age): self.age = age # 只绑定给s1 s1.set_age = MethodType(set_age,s1) s1.set_age(18) print(s1.age) # 18 # 新实例用不了这个方法 s2 = Student() # s2.set_age(20) 报错

3. 给整个类绑定方法(所有实例通用)

def set_score(self,score): self.score = score # 直接挂载到类上 Student.set_score = set_score s1.set_score(90) s2.set_score(80) print(s1.score,s2.score)

二、slots作用(重点)

1. 作用

限制类的实例只能绑定指定属性,禁止随意新增其他属性,约束实例属性,节省内存、防止乱加属性。

2. 语法格式

在类内部写:

__slots__ = ("属性1","属性2")

只能写元组,放允许添加的属性名。

3. 通俗实例

# 只允许实例添加 name 和 age class Student: __slots__ = ("name","age") s = Student() s.name = "小红" s.age = 20 # 报错!score不在允许列表里 # s.score = 99

报错原因:score没写入__slots__,禁止绑定。

三、slots两大使用规则

  1. 只约束当前父类实例,对子类默认无效
class Student: __slots__ = ("name","age") # 子类继承父类 class GradStudent(Student): pass g = GradStudent() g.score = 100 # 正常运行,不受父类slots限制
  1. 子类也写__slots__:子类允许属性 = 子类自身属性 + 父类__slots__属性
class GradStudent(Student): __slots__ = ("score") # 新增允许score g = GradStudent() g.name = "小李" g.age = 22 g.score = 95 # 都可以使用

四、使用场景(必记)

  1. 大量创建同类对象(学生、用户、员工),节省内存
  2. 规范代码,防止别人乱给实例加无关属性
  3. 固定实例结构,统一代码规范

五、极简学习思路

  1. __slots__:实例随便加属性,自由灵活
  2. __slots__:实例只能加规定属性,严格限制
  3. 继承关系:父类限制管不住子类,子类要限制必须自己写

课后练习题(基础 + 进阶)

练习 1 基础题

定义一个Person类,使用__slots__限制只能添加namegender两个属性,创建实例测试,尝试添加height看是否报错。

## 练习 1 基础题 # 定义一个`Person`类,使用`__slots__`限制只能添加`name`、`gender`两个属性,创建实例测试,尝试添加`height`看是否报错。 class Person: # __slots__ = ['name','gender']#❌️不能用列表[],要用元组() 如下 __slots__ = ('name','gender') s1=Person()#1创建实例 s1.name='小明'#2赋值 s1.gender='male'#2赋值 print(s1.name)#3打印 print(s1.gender)#3打印 # print(s1.height) s1.height='180'

参考答案

class Person: __slots__ = ("name","gender") p = Person() p.name = "张三" p.gender = "男" # p.height = 180 # 运行报错

练习 2 进阶题

写子类Teacher继承Person,子类新增允许属性subject,实现父类 + 子类属性都能使用。

class Person: # __slots__ = ['name','gender']#❌️不能用列表[],要用元组() 如下 __slots__ = ('name','gender') #1创建实例 s1=Person() #2赋值 s1.name='小明' s1.gender='male' #3打印 print(s1.name) print(s1.gender) print(s1.height) s1.height='180' # === class Teacher(Person): __slots__ = ('subject') s2=Teacher() s2.name='小红' s2.gender='female' # s2.subject=Teacher.subject# 删除错误多余赋值语句 s2.subject='未知' print(s2.name) print(s2.gender) print(s2.subject)

参考答案

class Person: __slots__ = ("name","gender") class Teacher(Person): __slots__ = ("subject") t = Teacher() t.name = "王老师" t.gender = "女" t.subject = "数学" print(t.name,t.subject)

练习 3 判断题

  1. __slots__可以用列表[]定义属性(× 只能元组)
  2. 父类写了__slots__,子类自动继承限制(×)#父类和子类都写__slots__,子类才会继承父类的属性。
  3. 动态绑定方法不受__slots__限制(√)

=分割线=from types import MethodType 什么意思

from types import MethodType核心作用:把普通函数,变成「类的实例方法」,让这个函数能像类里自带的方法一样,使用self访问实例的属性。

拆解理解(结合你之前的教程)

  1. 先看字面:from types import MethodType

    • types是 Python 自带的一个「工具模块」,专门处理和 “类型” 相关的操作;
    • MethodType是这个模块里的一个「工具类 / 函数」,核心功能是 “转换函数为实例方法”。
  2. 为什么需要它?(对应教程里的场景)

    教程中,我们定义了一个普通函数def set_age(self, age):``Student``self

    MethodType``self

结合教程实例(更直观)

from types import MethodType # 导入工具 class Student: pass # 普通函数(不是类里的方法) def set_age(self, age): self.age = age s1 = Student() # 用MethodType把set_age变成s1的实例方法,绑定给s1 s1.set_age = MethodType(set_age, s1) s1.set_age(18) # 此时能正常调用,self就是s1 print(s1.age) # 输出18,成功给s1添加age属性

关键补充(小白避坑)

  • MethodType绑定的方法,只属于当前实例(比如上面的s1),其他实例(比如s2 = Student())不能用这个方法;
  • 如果想让所有实例都能用这个方法,不用MethodType,直接给「类」绑定函数即可(教程里后面的Student.set_score = set_score)。

=分割线=理解:动态绑定方法不受__slots__限制

一句话总结

slots只管「属性」,不管「方法」!你给实例动态绑方法, 完全管不着,不会报错!

1. 先分清两个东西:属性 vs 方法

你一定要先分清这两个,不然永远晕:

属性 = 变量 / 数据

比如:

s1.name = "小明" # 属性 s1.age = 18 # 属性

slots就是管这个的!

方法 = 函数 / 动作

比如:

def run(self): print("跑") s1.run = run # 方法(动态绑定)

slots不管这个!

2. 直接看代码(一看就懂)

class Student: __slots__ = ('name',) # 只允许 name 属性

① 绑属性(不在 slots 里 → 报错)

s1 = Student() s1.age = 18 # ❌ 报错!因为 age 不在 __slots__

② 绑方法(随便绑 → 不报错!)

def set_age(self, age): self.age = age s1.set_age = set_age # ✅ 正常!不报错!

结论

slots 只限制属性,不限制方法!

所以这句话是对的:

动态绑定方法不受 slots 限制(√)

3. 终极记忆口诀

  • 属性 = 数据__slots__
  • 方法 = 函数__slots__不管

====

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询