@classmethod 与 @staticmethod
使用适当的装饰器定义类方法和静态方法。
@classmethod 与 @staticmethod 是 CoddyKit 上的免费 Python Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Python Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Python Academy 课程共包含 4 节课。
简介
@classmethod 将类作为第一个参数接收。@staticmethod 不会接收任何特殊参数。两者都定义在类中。
实例方法、类方法与静态方法
普通方法接收 self。类方法接收 cls。静态方法两者都不接收。请根据所需的数据选择合适的方法类型。
class Demo:
def instance(self): return 'instance'
@classmethod
def class_m(cls): return f'class: {cls.__name__}'
@staticmethod
def static_m(): return 'static'
d = Demo()
print(d.instance())
print(Demo.class_m())
print(Demo.static_m())将 @classmethod 用作工厂
最常见的用途是提供替代构造器。使用 Date.from_string('2024-01-15'),而不是在 __init__ 中进行解析。
class Date:
def __init__(self, y,m,d): self.y,self.m,self.d=y,m,d
@classmethod
def today(cls):
from datetime import date
d = date.today()
return cls(d.year, d.month, d.day)
def __repr__(self): return f'{self.y}-{self.m}-{self.d}'
print(Date.today())继承中的 @classmethod
类方法中的 cls 指向实际的子类,而不是基类。这样可以确保工厂方法在子类中正常工作。
class Animal:
@classmethod
def create(cls, name):
return cls(name)
def __init__(self, name): self.name = name
class Dog(Animal): pass
d = Dog.create('Rex')
print(type(d).__name__, d.name)使用 @staticmethod 实现工具功能
静态方法在逻辑上是与某个类归在一起的普通函数。它们无法访问类数据或实例数据。
class MathHelper:
@staticmethod
def clamp(value, lo, hi):
return max(lo, min(hi, value))
print(MathHelper.clamp(15, 0, 10))
print(MathHelper.clamp(-5, 0, 10))@staticmethod 与模块函数
如果函数不需要使用类,它也可以成为模块级函数。只有当函数在逻辑上属于该类时,才应使用 @staticmethod。
class Validator:
@staticmethod
def is_email(s): return '@' in s and '.' in s
print(Validator.is_email('user@example.com'))
print(Validator.is_email('not-an-email'))从实例调用
您可以在实例上调用 @classmethod 和 @staticmethod,但 cls 以及无第一个参数的行为不会改变。
class C:
@classmethod
def who(cls): return cls.__name__
@staticmethod
def pi(): return 3.14
c = C()
print(c.who())
print(c.pi())用于单例的类方法
类方法可以通过检查实例是否已经存在来实现单例模式。
class Singleton:
_instance = None
@classmethod
def get(cls):
if cls._instance is None:
cls._instance = cls()
return cls._instance
a = Singleton.get()
b = Singleton.get()
print(a is b)重写类方法
子类可以重写类方法。此时 cls 会指向子类,从而保持多态性。
class Base:
@classmethod
def info(cls): return f'{cls.__name__} info'
class Child(Base): pass
print(Base.info())
print(Child.info())使用 cls 进行类型检查
在类方法内部,cls 就是实际的类。请使用 cls() 创建实例,不要将类名硬编码。
class Shape:
@classmethod
def make(cls):
return cls() # NOT Shape()
class Square(Shape): pass
print(type(Square.make()).__name__)与 @property 结合使用
类级别的缓存值可以将 @classmethod 与类属性结合起来,实现整个类共享的缓存。
class Config:
_data = None
@classmethod
def load(cls):
if cls._data is None:
cls._data = {'debug': True}
return cls._data
print(Config.load())快速检查
@classmethod 中的 cls 是什么?
回顾
@classmethod 会获得 cls:用于工厂、替代构造器和单例。@staticmethod 不会获得特殊参数:用于工具功能。cls 指向实际的类(或子类)。
继续学习
进步非常出色!请继续学习,掌握下一个概念。
常见问题解答
「@classmethod 与 @staticmethod」课时是免费的吗?
是的 — 「@classmethod 与 @staticmethod」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Python Academy 课程的其余内容,请升级到 CoddyKit PRO。 Python Academy 课程共包含 4 节课。
「@classmethod 与 @staticmethod」这节课中我会学到什么?
使用适当的装饰器定义类方法和静态方法。 你通过在浏览器中直接运行的动手代码来练习 Python Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Python Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Python Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「@classmethod 与 @staticmethod」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Python Academy 课中编写并运行代码吗?
能。每节 Python Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 作为一等对象的函数
- 编写自定义装饰器
- @property 装饰器
- @classmethod 与 @staticmethod