一、类(Class)
精准定义
类是面向对象编程(OOP)的核心抽象结构,是用于创建实例(对象)的“模板”,它封装了一组具有相同属性(特征)和方法(行为)的对象的共同特征。类本身不占用运行时内存,仅用于定义结构;只有通过实例化生成对象后,才会分配内存空间。
Python中,类通过class关键字定义,所有类默认继承自object类(Python 3中,即使不写class 类名(object):,也会隐式继承),支持封装、继承、多态三大核心特性,且允许动态添加/修改属性和方法。
场景化示例(贴合实际开发)
python # 定义一个“学生”类,封装学生的共同属性(姓名、学号)和行为(选课、打印信息) class Student(object): # 显式继承object,规范写法 # 类属性:所有学生共享的固定数据(学校名称) school = "北京大学" # 构造方法(初始化方法):实例化时自动调用,用于初始化实例属性 # self是必选参数,代表当前创建的实例本身,不可省略 def __init__(self, name, student_id): # 实例属性:每个学生独有的数据,通过self绑定到实例 self.name = name # 学生姓名(实例独有) self.student_id = student_id # 学号(实例独有) self.courses = [] # 选课程列表(实例独有,初始为空) # 实例方法:描述学生的行为,第一个参数必须是self def choose_course(self, course_name): """学生选课的方法,将课程添加到选课程列表""" self.courses.append(course_name) def print_info(self): """打印学生的详细信息""" print(f"学号:{self.student_id},姓名:{self.name},学校:{self.school},已选课程:{self.courses}")
# 易错点提醒:1. __init__是双下划线(魔术方法),单下划线无效;2. self不可省略,也不能替换为其他名称(虽可自定义,但不符合规范)
|
二、实例(对象,Instance / Object)
精准定义
实例(对象)是通过类实例化得到的具体实体,是类的“具象化体现”。每个实例都拥有类定义的属性和方法,但会有自己独立的实例属性值,占用独立的运行时内存,实例之间的属性互不干扰。
实例化语法:实例名 = 类名(参数),参数需与类的__init__方法中除self外的参数对应(无额外参数则不传)。
场景化示例(承接上面的Student类)
python # 实例化:创建2个不同的学生实例(对象) stu1 = Student("张三", "2024001") # 传入name和student_id参数,触发__init__初始化 stu2 = Student("李四", "2024002")
# 访问实例属性:实例名.属性名 print(stu1.name) # 输出:张三(仅属于stu1的实例属性) print(stu2.student_id) # 输出:2024002(仅属于stu2的实例属性) print(stu1.school) # 输出:北京大学(访问类属性,所有实例共享)
# 调用实例方法:实例名.方法名(参数) stu1.choose_course("Python编程") stu2.choose_course("高等数学") stu2.choose_course("英语")
# 打印学生信息,体现实例属性的独立性 stu1.print_info() # 输出:学号:2024001,姓名:张三,学校:北京大学,已选课程:['Python编程'] stu2.print_info() # 输出:学号:2024002,姓名:李四,学校:北京大学,已选课程:['高等数学', '英语']
# 易错点提醒:实例不能直接调用类的魔术方法(如__init__),需通过类名调用(不推荐新手操作)
|
三、方法(Method)
精准定义
方法是定义在类内部的函数,用于描述类或实例的行为,与普通函数的区别是:方法必须绑定到类或实例上才能调用,且有固定的默认第一个参数(self/cls)。Python中方法分为三类,用途明确,不可混淆。
1. 实例方法(最常用,核心)
绑定到实例的方法,第一个参数必须是self(代表当前实例),只能通过实例调用,可直接访问/修改实例属性和类属性。
python # 承接Student类,新增实例方法(修改姓名) class Student(object): school = "北京大学" def __init__(self, name, student_id): self.name = name self.student_id = student_id # 实例方法:修改实例属性name def update_name(self, new_name): self.name = new_name # 通过self访问并修改实例属性
# 调用实例方法 stu1 = Student("张三", "2024001") stu1.update_name("张三丰") print(stu1.name) # 输出:张三丰(实例属性已修改)
|
2. 类方法(@classmethod 装饰器)
绑定到类的方法,需用@classmethod装饰器修饰,第一个参数必须是cls(代表当前类),可通过类或实例调用,**只能访问/修改类属性,不能直接访问实例属性**(除非传入实例)。
python class Student(object): school = "北京大学" # 类属性 count = 0 # 类属性:统计学生实例的数量 def __init__(self, name, student_id): self.name = name self.student_id = student_id Student.count += 1 # 实例化时,类属性count自增 # 类方法:修改类属性school,统计学生数量 @classmethod def update_school(cls, new_school): cls.school = new_school # 通过cls访问并修改类属性 @classmethod def get_student_count(cls): return cls.count # 通过cls访问类属性
# 调用类方法(两种方式,推荐用类名调用) Student.update_school("清华大学") # 类调用 stu1 = Student("张三", "2024001") stu1.update_school("复旦大学") # 实例调用(不推荐,语义不清晰)
print(Student.school) # 输出:复旦大学(类属性已修改) print(stu1.school) # 输出:复旦大学(所有实例共享类属性) print(Student.get_student_count()) # 输出:1(统计实例数量)
# 易错点提醒:类方法不能直接访问self.xxx(实例属性),会报错
|
3. 静态方法(@staticmethod 装饰器)
不绑定到类或实例的方法,需用@staticmethod装饰器修饰,**无默认参数(无self/cls)**,本质是“放在类里的普通函数”,不能直接访问类属性和实例属性(除非手动传入类/实例),仅用于封装与类相关的工具函数。
python class Student(object): school = "北京大学" # 静态方法:工具函数,判断学号是否合法(仅与学生类相关,无依赖) @staticmethod def is_valid_student_id(student_id): # 无self/cls,不能直接访问school或实例属性 return len(student_id) == 6 and student_id.startswith("2024")
# 调用静态方法(两种方式,均可) print(Student.is_valid_student_id("2024001")) # 输出:True(合法) print(Student.is_valid_student_id("202401")) # 输出:False(不合法)
stu1 = Student("张三", "2024001") print(stu1.is_valid_student_id("2024002")) # 输出:True
# 易错点提醒:静态方法不能直接使用self/cls,若需访问类/实例属性,需手动传入
|
四、类属性(Class Attribute / Class Variable)
精准定义
类属性是定义在**类内部、所有方法外部**的属性,属于类本身,**所有实例共享同一份数据**,内存中仅存储一份,修改类属性会影响所有实例对该属性的访问结果。
用途:存储所有实例共用的固定数据(如学校名称、默认配置、计数器等),避免重复创建相同数据,节省内存。
场景化示例(区分“类属性修改”与“实例属性覆盖”)
python class Teacher(object): # 类属性:所有老师共享 department = "计算机学院" # 院系 salary_base = 8000 # 基础工资 def __init__(self, name): self.name = name # 实例属性:老师姓名
# 1. 访问类属性(类、实例均可访问) print(Teacher.department) # 输出:计算机学院(类访问,推荐) t1 = Teacher("王老师") print(t1.department) # 输出:计算机学院(实例访问,本质是访问类属性)
# 2. 修改类属性(只能通过类名修改,实例修改会创建新的实例属性,覆盖类属性) Teacher.salary_base = 9000 # 类修改类属性,所有实例生效 t2 = Teacher("李老师") print(t1.salary_base) # 输出:9000(生效) print(t2.salary_base) # 输出:9000(生效)
# 3. 易错点:实例“修改”类属性(实际是创建实例属性,覆盖类属性,不影响其他实例和类) t1.department = "软件学院" # 给t1创建实例属性department,覆盖类属性 print(t1.department) # 输出:软件学院(实例属性) print(t2.department) # 输出:计算机学院(类属性,未被修改) print(Teacher.department) # 输出:计算机学院(类属性,未被修改)
|
五、实例属性(Instance Attribute / Instance Variable)
精准定义
实例属性是绑定在实例(self)上的属性,通常在__init__方法中通过self.属性名 = 值定义,也可在实例创建后动态添加。每个实例拥有独立的实例属性副本,内存中单独存储,实例之间的实例属性互不干扰。
用途:存储每个实例独有的个性化数据(如姓名、学号、年龄等)。
场景化示例(动态添加/修改/删除实例属性)
python class Book(object): # 类属性:所有书籍共享 type = "纸质书" # __init__中定义实例属性 def __init__(self, title, author): self.title = title # 书名(实例独有) self.author = author # 作者(实例独有)
# 1. 实例化,初始化实例属性 book1 = Book("Python编程:从入门到精通", "张三") book2 = Book("数据结构与算法", "李四")
# 2. 访问实例属性 print(book1.title) # 输出:Python编程:从入门到精通 print(book2.author) # 输出:李四
# 3. 动态添加实例属性(实例创建后,额外添加属性) book1.price = 59.9 # 给book1添加实例属性price # print(book2.price) # 报错:book2没有price属性(实例属性独立)
# 4. 动态修改实例属性 book1.author = "张三丰" print(book1.author) # 输出:张三丰
# 5. 删除实例属性(del关键字) del book1.price # print(book1.price) # 报错:price已被删除
# 易错点提醒:实例属性仅属于当前实例,不能通过一个实例修改另一个实例的属性 |
六、局部变量(Local Variable)
精准定义
局部变量是定义在**方法内部**(包括实例方法、类方法、静态方法)的变量,作用域仅限于当前方法,**方法执行开始时创建,方法执行结束后自动销毁**,无法被类的其他方法、实例或外部代码访问。
用途:用于方法内部的临时计算、中间结果存储,不影响类和实例的属性。
场景化示例(明确局部变量的作用域)
python class Calculator(object): # 类属性 pi = 3.14159 # 实例方法:计算圆的面积 def circle_area(self, radius): # 局部变量:仅在circle_area方法内部有效 square_radius = radius * radius # 临时计算半径的平方 area = self.pi * square_radius # 临时计算面积 return area # 返回局部变量的值
# 调用方法 calc = Calculator() print(calc.circle_area(5)) # 输出:78.53975(正常返回)
# 易错点:外部无法访问局部变量 # print(square_radius) # 报错:name 'square_radius' is not defined # print(area) # 报错:name 'area' is not defined
# 补充:局部变量与实例属性的区别(避免混淆) def test_method(self): temp = 10 # 局部变量(方法内有效) self.temp = 20 # 实例属性(实例内有效)
|
七、继承(Inheritance)
精准定义
继承是面向对象编程的核心复用机制,允许子类(派生类,Derived Class)继承父类(基类,Base Class)的所有非私有属性和方法,子类无需重复定义,同时可扩展新的属性/方法,或重写父类的方法以实现个性化功能。
Python支持单继承(一个子类继承一个父类)和多继承(一个子类继承多个父类,语法:class 子类名(父类1, 父类2, ...):),遵循“方法解析顺序(MRO)”查找属性/方法。
关键术语:父类(基类)、子类(派生类)、重写(Override,子类重新定义父类的方法)、继承链(多个继承关系形成的链条)。
场景化示例(单继承+重写+扩展)
python # 父类:动物类(封装所有动物的共同属性和行为) class Animal(object): def __init__(self, name, age): self.name = name # 所有动物都有姓名 self.age = age # 所有动物都有年龄 # 父类方法:所有动物的共同行为(进食) def eat(self): print(f"{self.name}正在进食...")
# 子类:猫类(继承Animal,扩展自己的行为,重写父类方法) class Cat(Animal): # 继承Animal,Cat是子类,Animal是父类 # 扩展新的实例属性(猫独有的“毛色”) def __init__(self, name, age, color): # 调用父类的__init__方法,复用父类的属性初始化(避免重复代码) super().__init__(name, age) # 推荐用super(),兼容多继承 # 新增子类的实例属性 self.color = color # 重写父类的eat方法(猫的进食行为与普通动物不同) def eat(self): print(f"{self.color}的{self.name}({self.age}岁)正在吃猫粮...") # 扩展新的方法(猫独有的行为:喵喵叫) def meow(self): print(f"{self.name}喵喵叫~")
# 子类:狗类(继承Animal,仅重写方法,不扩展新属性) class Dog(Animal): # 重写父类的eat方法 def eat(self): print(f"{self.name}({self.age}岁)正在吃狗粮...")
# 测试继承、重写、扩展 cat1 = Cat("小白", 2, "白色") cat1.eat() # 输出:白色的小白(2岁)正在吃猫粮...(重写后的方法) cat1.meow() # 输出:小白喵喵叫~(扩展的方法) print(cat1.color) # 输出:白色(扩展的属性)
dog1 = Dog("大黄", 3) dog1.eat() # 输出:大黄(3岁)正在吃狗粮...(重写后的方法)
# 易错点提醒:1. 子类重写__init__时,必须调用父类的__init__(否则父类属性无法初始化);2. super()无需传入self,自动绑定
|
八、核心逻辑梳理(精准连贯)
1. 类:定义“模板”,封装所有实例的共同属性(类属性)和行为(方法),不占用运行时内存,是实例化的基础。
2. 实例(对象):类的具象化产物,通过实例化创建,占用独立内存,拥有自己的实例属性,可调用类的方法,是程序运行时实际操作的实体。
3. 类属性:属于类,所有实例共享,用于存储共用数据,仅能通过类名修改。
4. 实例属性:属于实例,每个实例独立拥有,用于存储个性化数据,可动态添加/修改/删除。
5. 方法:类/实例的行为,分三类——实例方法(操作实例)、类方法(操作类)、静态方法(工具函数),各有固定用途,不可混淆。
6. 局部变量:方法内部的临时变量,作用域仅限于方法,执行完毕后销毁,与类/实例属性无关。
7. 继承:实现代码复用,子类继承父类的非私有成员,可重写父类方法、扩展新功能,形成继承链。
核心关系:类 → 实例化 → 对象;类属性(共享)+ 实例属性(独立)→ 对象的特征;方法 → 对象/类的行为;继承 → 扩展与复用。
补充:关键易错点汇总(必看)
• self是实例方法的第一个必选参数,代表当前实例;cls是类方法的第一个必选参数,代表当前类,不可省略。
• 类属性只能通过类名修改,实例修改类属性会创建新的实例属性,覆盖类属性(不影响其他实例和类)。
• 子类重写__init__时,必须通过super()调用父类的__init__,否则父类的属性无法初始化。
• 局部变量仅在方法内部有效,外部无法访问;实例属性可通过实例访问,类属性可通过类/实例访问。
• 静态方法无self/cls参数,不能直接访问类/实例属性;类方法不能直接访问实例属性。