第54集:实例方法与self
学习目标
- 理解实例方法的概念和作用
- 掌握self参数的含义和用法
- 学会通过self访问和修改实例属性
- 理解实例方法、类方法、静态方法的区别
- 掌握实例方法的调用方式
- 学会在实例方法中调用其他方法
一、实例方法概述
1.1 什么是实例方法
实例方法:定义在类中,第一个参数是self的方法,用于操作对象的属性和执行对象的行为。
1.2 语法格式
class ClassName:
def method_name(self, 参数1, 参数2, ...):
# 方法体
# 可以使用self访问和修改实例属性
pass1.3 基本示例
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def say_hello(self):
"""实例方法:自我介绍"""
print(f"大家好,我是{self.name},今年{self.age}岁")
# 创建对象
p = Person("张三", 18)
p.say_hello() # 输出:大家好,我是张三,今年18岁二、self参数详解
2.1 self的含义
self代表什么:
self代表当前对象实例- 它是对调用方法的对象的引用
示例:
class Demo:
def show_self(self):
print(f"self的值: {self}")
print(f"self的类型: {type(self)}")
d1 = Demo()
d1.show_self()
# 输出:
# self的值: <__main__.Demo object at 0x...>
# self的类型: <class '__main__.Demo'>
d2 = Demo()
d2.show_self()
# 输出:
# self的值: <__main__.Demo object at 0x...> (不同的地址)2.2 self的自动传递
class Person:
def __init__(self, name):
self.name = name
def greet(self, other):
print(f"{self.name}向{other.name}打招呼")
p1 = Person("张三")
p2 = Person("李四")
# 方法调用时,Python自动传递对象作为self
p1.greet(p2) # 实际上是: Person.greet(p1, p2)
# 输出:张三向李四打招呼2.3 多个对象各自独立的self
class Counter:
def __init__(self):
self.count = 0
def increment(self):
self.count += 1
print(f"当前计数: {self.count}")
c1 = Counter()
c2 = Counter()
c1.increment() # 输出:当前计数: 1
c1.increment() # 输出:当前计数: 2
c2.increment() # 输出:当前计数: 1 (独立的)三、通过self访问属性
3.1 访问实例属性
class Student:
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score
def display_info(self):
"""显示学生信息"""
# 通过self访问实例属性
print(f"姓名: {self.name}")
print(f"年龄: {self.age}")
print(f"成绩: {self.score}")
s = Student("张三", 18, 90)
s.display_info()3.2 修改实例属性
class BankAccount:
def __init__(self, balance):
self.balance = balance
def deposit(self, amount):
"""存款"""
# 通过self修改实例属性
self.balance += amount
def withdraw(self, amount):
"""取款"""
self.balance -= amount
account = BankAccount(1000)
account.deposit(500)
print(account.balance) # 输出:1500
account.withdraw(200)
print(account.balance) # 输出:13003.3 动态添加属性
class Person:
def __init__(self, name):
self.name = name
def add_attribute(self, attr_name, attr_value):
"""动态添加属性"""
setattr(self, attr_name, attr_value)
p = Person("张三")
p.add_attribute("age", 18)
p.add_attribute("city", "北京")
print(p.age) # 输出:18
print(p.city) # 输出:北京四、在实例方法中调用其他方法
4.1 调用其他实例方法
class Calculator:
def __init__(self, value):
self.value = value
def add(self, other):
self.value += other
return self
def multiply(self, other):
self.value *= other
return self
def display(self):
print(f"当前值: {self.value}")
calc = Calculator(10)
calc.add(5).multiply(2).display()
# 输出:当前值: 304.2 方法间的协作
class Student:
def __init__(self, name, scores):
self.name = name
self.scores = scores
def calculate_average(self):
"""计算平均分"""
if not self.scores:
return 0
return sum(self.scores) / len(self.scores)
def get_grade(self):
"""获取等级"""
average = self.calculate_average() # 调用另一个方法
if average >= 90:
return "A"
elif average >= 80:
return "B"
elif average >= 70:
return "C"
elif average >= 60:
return "D"
else:
return "F"
def display_report(self):
"""显示成绩报告"""
print(f"学生: {self.name}")
print(f"各科成绩: {self.scores}")
print(f"平均分: {self.calculate_average():.2f}")
print(f"等级: {self.get_grade()}")
s = Student("张三", [85, 90, 78, 92, 88])
s.display_report()五、实例方法 vs 类方法 vs 静态方法
5.1 对比表
| 特性 | 实例方法 | 类方法 | 静态方法 |
|---|---|---|---|
| 第一个参数 | self | cls | 无 |
| 装饰器 | 无 | @classmethod | @staticmethod |
| 访问 | 实例属性和方法 | 类属性和方法 | 不访问属性 |
| 调用方式 | 对象名 | 类名或对象名 | 类名或对象名 |
| 用途 | 操作对象数据 | 操作类数据 | 工具函数 |
5.2 示例对比
class MyClass:
class_attr = "类属性"
def __init__(self):
self.instance_attr = "实例属性"
# 实例方法
def instance_method(self):
print(f"实例方法: self={self}")
print(f" 实例属性: {self.instance_attr}")
print(f" 类属性: {MyClass.class_attr}")
# 类方法
@classmethod
def class_method(cls):
print(f"类方法: cls={cls}")
print(f" 类属性: {cls.class_attr}")
# 静态方法
@staticmethod
def static_method():
print("静态方法: 不访问任何属性")
# 使用
obj = MyClass()
obj.instance_method()
MyClass.class_method()
MyClass.static_method()六、常见应用场景
6.1 数据处理
class DataProcessor:
def __init__(self, data):
self.data = data
def filter(self, condition):
"""过滤数据"""
return [item for item in self.data if condition(item)]
def transform(self, func):
"""转换数据"""
self.data = [func(item) for item in self.data]
return self
def aggregate(self, func):
"""聚合数据"""
return func(self.data)
processor = DataProcessor([1, 2, 3, 4, 5])
result = processor.filter(lambda x: x > 2).transform(lambda x: x ** 2).aggregate(sum)
print(result) # 输出:54 (3² + 4² + 5²)6.2 状态管理
class GamePlayer:
def __init__(self, name):
self.name = name
self.health = 100
self.level = 1
self.experience = 0
def take_damage(self, damage):
"""受到伤害"""
self.health -= damage
if self.health < 0:
self.health = 0
print(f"{self.name}受到{damage}点伤害,剩余生命: {self.health}")
def heal(self, amount):
"""治疗"""
self.health += amount
if self.health > 100:
self.health = 100
print(f"{self.name}恢复{amount}点生命,当前生命: {self.health}")
def gain_experience(self, exp):
"""获得经验"""
self.experience += exp
if self.experience >= self.level * 100:
self.level_up()
def level_up(self):
"""升级"""
self.level += 1
self.health = 100 # 升级恢复满血
print(f"{self.name}升级了!当前等级: {self.level}")
player = GamePlayer("英雄")
player.take_damage(30)
player.heal(20)
player.gain_experience(120)七、常见错误与注意事项
7.1 常见错误
- 忘记self参数:
class Person:
def say_hello(): # 错误:缺少self
print("你好!")- 调用方法时传递self:
class Person:
def greet(self):
print("你好!")
p = Person()
p.greet(p) # 错误:不需要传递self- 在类方法中错误使用self:
class MyClass:
@classmethod
def class_method(cls):
self.value = 10 # 错误:类方法应该使用cls7.2 注意事项
- 实例方法必须有self作为第一个参数
- 调用方法时不需要手动传递self
- 通过self可以访问所有实例属性和方法
- 一个对象的方法可以访问另一个对象的属性
八、课后练习
练习题
编程题
- 定义一个
Rectangle类,包含长和宽属性 - 添加计算面积、周长的方法
- 添加判断是否为正方形的方法
- 定义一个
编程题
- 定义一个
BankAccount类 - 添加存款、取款、查询余额方法
- 添加计算利息的方法
- 定义一个
思考题
- 为什么实例方法的第一个参数必须是self?
- 类方法和实例方法有什么区别?
- 什么时候应该使用静态方法?
九、本集总结
核心知识点回顾
- 实例方法:第一个参数是self的方法
- self的作用:代表当前对象实例
- 访问属性:通过self访问和修改实例属性
- 调用方法:在实例方法中调用其他实例方法
- 三种方法对比:实例方法、类方法、静态方法
下集预告
下一集我们将学习封装特性,深入了解如何使用访问修饰符来保护数据。
学习建议: 熟练掌握self的使用,理解实例方法的工作原理。通过编写实际的类来练习实例方法的应用。