静态方法与类方法
本课属于 Coddy Python 学习旅程的“面向对象编程”单元。第 39 课,共 64 课。
除了常规的实例方法,类还可以有静态方法和类方法,它们的用途各不相同。
下面是一个静态方法的示例:
class MathHelper:
@staticmethod
def add(a, b):
return a + b
@staticmethod
def is_even(number):
return number % 2 == 0静态方法不需要 self,其工作方式与普通函数相同。直接通过类调用它们:
result = MathHelper.add(5, 3)
print(result)
check = MathHelper.is_even(10)
print(check)下面是一个类方法的示例:
class Person:
count = 0 # 类变量
def __init__(self, name):
self.name = name
Person.count += 1
@classmethod
def get_count(cls):
return cls.count
@classmethod
def create_anonymous(cls):
return cls("Anonymous")类方法会将类本身(cls)作为第一个参数接收:
person1 = Person("Alice")
person2 = Person("Bob")
print(Person.get_count()) # 2使用类方法作为替代构造函数:
anonymous = Person.create_anonymous()
print(anonymous.name) # 匿名
print(Person.get_count()) # 3在一个类中比较这三种方法:
class Calculator:
brand = "Python Calc"
def __init__(self, owner):
self.owner = owner
# 实例方法:需要 self,可访问实例数据
def show_owner(self):
return f"Owned by {self.owner}"
# 类方法:需要 cls,可访问类数据
@classmethod
def get_brand(cls):
return cls.brand
# 静态方法:两者都不需要,只是一个工具函数
@staticmethod
def multiply(x, y):
return x * ycalc = Calculator("Alice")
print(calc.show_owner()) # 归 Alice 所有
print(Calculator.get_brand()) # Python Calc
print(Calculator.multiply(4, 5)) # 20输出:
8
True
2
Anonymous
3
Owned by Alice
Python Calc
20你也可以通过实例调用类方法和静态方法:
calc = Calculator("Bob")
print(calc.get_brand()) # Python Calc
print(calc.multiply(2, 3)) # 6主要区别:
- 实例方法:需要
self,可以访问实例数据 - 类方法:需要
cls,可以访问类数据,适合用作替代构造函数 - 静态方法:两者都不需要,只是与类相关的实用函数
关键点:对于逻辑上属于类、但不需要类或实例数据的实用函数,使用 @staticmethod。当你需要访问类本身时,例如创建替代构造函数或访问类变量,则使用 @classmethod。
挑战
简单在这个挑战中,你将实现一个具有特定功能的 Temperature 类,并使用全面的测试框架。
你只需要编辑 temperature.py 文件,并按照指导你完成实现的 TODO 注释操作。这个类应包含:
- 一个用于跟踪温度读数的类变量
- 一个用于温度转换的静态方法
- 用于添加读数和计算平均值的类方法
亲手试试
from temperature import Temperature
# 用于全面测试的测试用例处理程序
test_case = input()
if test_case == "default_test":
# 测试基本功能
Temperature.celsius_readings = []
Temperature.add_reading(25)
Temperature.add_reading(30)
Temperature.add_reading(27)
print(f"Average reading: {Temperature.average_reading()}")
print(f"22°C is {Temperature.celsius_to_fahrenheit(22)}°F")
elif test_case == "empty_readings":
# 测试没有读数时的 average_reading
Temperature.celsius_readings = []
print(f"Average reading: {Temperature.average_reading()}")
elif test_case == "single_reading":
# 使用单个读数进行测试
Temperature.celsius_readings = []
Temperature.add_reading(100)
print(f"Average reading: {Temperature.average_reading()}")
elif test_case == "negative_values":
# 使用负温度值进行测试
Temperature.celsius_readings = []
Temperature.add_reading(-10)
Temperature.add_reading(-20)
Temperature.add_reading(-30)
print(f"Average reading: {Temperature.average_reading()}")
print(f"-15°C is {Temperature.celsius_to_fahrenheit(-15)}°F")
elif test_case == "zero_value":
# 使用 0°C 的读数进行测试
print(f"0°C is {Temperature.celsius_to_fahrenheit(0)}°F")
elif test_case == "extreme_values":
# 使用极端温度值进行测试
absolute_zero = -273.15 # 以摄氏度表示的绝对零度
sun_surface = 5500 # 以摄氏度表示的太阳表面近似温度
print(f"{absolute_zero}°C is {Temperature.celsius_to_fahrenheit(absolute_zero)}°F")
print(f"{sun_surface}°C is {Temperature.celsius_to_fahrenheit(sun_surface)}°F")
elif test_case == "reset_readings":
# 测试重置读数
Temperature.celsius_readings = []
Temperature.add_reading(10)
Temperature.add_reading(20)
Temperature.add_reading(30)
print(f"Average reading before reset: {Temperature.average_reading()}")
Temperature.celsius_readings = []
print(f"Average reading after reset: {Temperature.average_reading()}")
elif test_case == "decimal_values":
# 使用小数值进行测试
Temperature.celsius_readings = []
Temperature.add_reading(36.5) # 正常体温
Temperature.add_reading(37.2) # 轻微发烧
Temperature.add_reading(36.9) # 正常波动
print(f"Average reading: {Temperature.average_reading()}")
elif test_case == "many_readings":
# 用多个温度读数进行测试
Temperature.celsius_readings = []
for i in range(1, 101):
Temperature.add_reading(i)
print(f"Average reading with 100 values: {Temperature.average_reading()}")这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Python 在线编译器