实例方法
在类中,最常见、最重要的函数是实例方法,它的第一个参数永远是 self,代表类的实例(对象)本身,通过 self,方法可以访问和修改实例的属性(变量),以及调用其他实例方法。

定义和调用实例方法
定义
当你定义一个类时,在函数内部使用 self 作为第一个参数,它就变成了一个实例方法。
调用
调用实例方法必须通过类的实例(对象)来进行,语法是 实例名.方法名()。
代码示例
class Dog:
# 这是一个特殊方法,称为构造函数,在创建实例时自动调用
def __init__(self, name, age):
print(f"创建了一只名叫 {name} 的狗!")
# self.name 和 self.age 是实例的属性
self.name = name
self.age = age
# 这是一个实例方法
def bark(self):
"""让狗叫"""
print(f"{self.name} 正在汪汪叫!")
# 另一个实例方法,可以访问实例属性
def celebrate_birthday(self):
"""让狗过生日"""
self.age += 1
print(f"祝 {self.name} 生日快乐!它现在 {self.age} 岁了。")
# --- 创建类的实例(对象) ---
my_dog = Dog("旺财", 2)
another_dog = Dog("小黑", 1)
# --- 调用实例方法 ---
# 必须通过实例来调用
my_dog.bark() # 输出: 旺财 正在汪汪叫!
# 调用另一个方法,它会修改实例的属性
my_dog.celebrate_birthday() # 输出: 祝 旺财 生日快乐!它现在 3 岁了。
# 再次调用,可以看到属性已经被修改了
my_dog.bark() # 输出: 旺财 正在汪汪叫!
# 另一个实例的方法调用不会影响这个实例
another_dog.bark() # 输出: 小黑 正在汪汪叫!
关键点:
self是由 Python 解释器自动传入的,当你调用my_dog.bark()时,Python 会自动将my_dog这个实例作为第一个参数传给bark方法的self,所以你不需要,也不能自己传递self。self是连接方法与实例的桥梁,没有self,方法就无法知道它应该操作哪个具体的数据。
类方法
类方法不依赖于实例,而是依赖于类本身,它的第一个参数是 cls,代表类,类方法通常用于操作与类相关的数据,而不是实例数据。

定义
使用 @classmethod 装饰器来定义。
调用
可以通过类名或实例名来调用,推荐使用类名调用,以表明它是一个类方法。
代码示例
class Dog:
# 类属性,所有实例共享
species = "犬科"
def __init__(self, name):
self.name = name
# 实例方法
def introduce(self):
print(f"我叫 {self.name},我的物种是 {Dog.species}") # 也可以用 self.species
# 类方法
@classmethod
def get_species_info(cls):
"""返回物种信息"""
# cls 指向 Dog 这个类
print(f"这是一个 {cls.__name__} 类,所有成员都属于 {cls.species} 这个物种。")
# --- 调用类方法 ---
# 推荐使用类名调用
Dog.get_species_info()
# 输出: 这是一个 Dog 类,所有成员都属于 犬科 这个物种。
# 也可以通过实例调用,但不太推荐
my_dog = Dog("旺财")
my_dog.get_species_info()
# 输出: 这是一个 Dog 类,所有成员都属于 犬科 这个物种。
静态方法
静态方法与类和实例都没有直接关系,它只是一个“依附”在类上的普通函数,当你需要这个函数与类相关,但又不希望它访问任何类或实例的数据时,就可以使用它。
定义
使用 @staticmethod 装饰器来定义。

调用
同样可以通过类名或实例名来调用。
代码示例
class Dog:
def __init__(self, name):
self.name = name
# 静态方法
@staticmethod
def is_valid_sound(sound):
"""检查一个声音是否是狗的有效叫声"""
# 它不访问 self 或 cls
return sound in ["汪汪", "呜呜", "嗷呜"]
# --- 调用静态方法 ---
# 推荐使用类名调用
print(Dog.is_valid_sound("汪汪")) # 输出: True
print(Dog.is_valid_sound("喵喵")) # 输出: False
# 也可以通过实例调用
my_dog = Dog("旺财")
print(my_dog.is_valid_sound("呜呜")) # 输出: True
在类的方法中调用其他方法
这是非常常见的操作,通常是为了避免重复代码,或者将一个复杂的功能分解成多个小功能。
代码示例
class Calculator:
def __init__(self, value):
self.value = value
def add(self, number):
"""加法"""
self.value += number
return self
def subtract(self, number):
"""减法"""
self.value -= number
return self
def multiply(self, number):
"""乘法"""
self.value *= number
return self
def print_result(self):
"""打印当前结果"""
print(f"当前计算结果是: {self.value}")
# 复杂的计算,通过调用其他简单方法实现
def complex_calculation(self, a, b, c):
"""执行一个复杂的计算: (value + a) * b - c"""
print("开始复杂计算...")
self.add(a) # 调用 add 方法
self.multiply(b) # 调用 multiply 方法
self.subtract(c) # 调用 subtract 方法
self.print_result() # 调用 print_result 方法
return self.value
# --- 演示 ---
calc = Calculator(10)
# 执行 (10 + 5) * 2 - 3 = 27
final_result = calc.complex_calculation(5, 2, 3)
# 输出:
# 开始复杂计算...
# 当前计算结果是: 27
print(f"最终返回值: {final_result}") # 输出: 最终返回值: 27
调用父类的方法
在继承中,子类可以重写(override)父类的方法,如果子类在重写的方法中,还想执行父类原来的方法,就需要显式地调用它。
定义与调用
使用 super().父类方法名() 的形式。
代码示例
class Animal:
def __init__(self, name):
self.name = name
print(f"动物 {self.name} 被创建了。")
def make_sound(self):
print("动物发出声音。")
class Dog(Animal): # Dog 继承自 Animal
def __init__(self, name, breed):
# 调用父类的 __init__ 方法
super().__init__(name)
self.breed = breed
print(f"一只品种为 {self.breed} 的狗 {self.name} 创建完成。")
# 重写父类的 make_sound 方法
def make_sound(self):
print("汪汪!") # 先执行自己的逻辑
# 再调用父类的 make_sound 方法
super().make_sound()
# --- 演示 ---
my_dog = Dog("旺财", "中华田园犬")
print("-" * 20)
my_dog.make_sound()
# 输出:
# 动物 旺财 被创建了。
# 一只品种为 中华田园犬 的狗 旺财 创建完成。
# --------------------
# 汪汪!
# 动物发出声音。
| 方法类型 | 定义方式 | 第一个参数 | 调用方式 | 主要用途 |
|---|---|---|---|---|
| 实例方法 | def method(self, ...): |
self (实例) |
instance.method() |
操作和修改实例的状态(属性) |
| 类方法 | @classmethoddef method(cls, ...): |
cls (类) |
Class.method() 或 instance.method() |
操作与类相关的状态,通常用作工厂方法 |
| 静态方法 | @staticmethoddef method(...): |
无 | Class.method() 或 instance.method() |
与类或实例无关的工具函数,逻辑上属于类的一部分 |
| 父类方法 | super().parent_method() |
无(自动处理) | 在子类方法内部调用 | 在子类中重写父类方法后,希望保留并扩展父类功能 |
理解这几种方法的区别和调用方式,是掌握 Python 面向对象编程的关键。
