0Pricing
Python Academy · 课时

@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 反馈 — 无需本地设置。

此课程中的所有课时

  1. 作为一等对象的函数
  2. 编写自定义装饰器
  3. @property 装饰器
  4. @classmethod 与 @staticmethod
← 返回 Python Academy