Python中self与cls的区别及@staticmethod与@classmethod用法详解

山海之间
山海之间
发布时间:2026-10-14| 3人浏览过
原创

本文详细解析Python中self与cls的区别,以及@staticmethod和@classmethod装饰器的使用场景。通过代码示例对比静态方法、类方法与实例方法的调用方式,阐明参数传递机制及适用场景,帮助开发者正确组织代码结构。

Python中self与cls概念解析

Python中的self与cls概念解析

核心区别在于:self代表类的实例对象,而cls代表类本身(或子类),具体取决于调用上下文。此外,@staticmethod用于定义静态方法装饰器,@classmethod用于定义类方法装饰器。理解这两者需要从声明定义与实际调用两个维度入手。

详细机制分析

详细机制分析

通常情况下,调用类的方法需要先实例化对象。但使用@staticmethod或@classmethod装饰器后,可以直接通过类名.方法名()的方式调用,无需实例化。这种设计有助于代码组织,将属于特定类的函数归置到该类中,同时保持命名空间的整洁。

类方法定义与调用方式

首先定义一个类A,其中包含三个方法:foo1为静态方法,使用@staticmethod装饰;foo2为普通实例方法;foo3为类方法,使用@classmethod装饰。静态方法与类有关联,但不依赖实例或类本身参与计算。


class A(object):
 a = 'a'
 @staticmethod
 def foo1(name):
 print('hello', name, A.a)
 def foo2(self, name):
 print('hello', name, self.a)
 @classmethod
 def foo3(cls, name):
 print('hello', name, cls.a)
class B(A):
 a = 'b'
 @staticmethod
 def foo1(name):
 print('hello', name, B.a)
 def foo2(self, name):
 print('subclass B')
 print('hello', name, self.a)
 @classmethod
 def foo3(cls, name):
 print('hello', name, cls.a)

以下两种调用方式均能正常输出结果,说明静态方法具有灵活性:

静态方法既可以通过类名直接调用,也可以通过类的实例对象调用。


a = A()
b = B()
a.foo1("小熊猫") # hello 小熊猫 
A.foo1("小熊猫") # hello 小熊猫 
b.foo1("大熊猫") # subclass B, hello 大熊猫 b
B.foo1("大熊猫") # subclass B, hello 大熊猫 b

foo2是标准的实例方法,其调用方式如下所示:

通过传入实例对象或类名称作为self参数,可以访问不同的属性和方法。


a.foo2("小熊猫") # hello 小熊猫 a
A.foo2(a, "小熊猫") # hello 小熊猫 a
A.foo2(b, "小熊猫") # hello 小熊猫 b
A.foo2(A, "小熊猫") # hello 小熊猫 a 
A.foo2(B, "小熊猫") # hello 小熊猫 b
B.foo2(a, "小熊猫") # subclass B, hello 小熊猫 a

foo3是类方法,cls作为第一个参数表示类本身。类方法仅与类相关,而与具体实例无关。以下两种调用方式均能正常执行:

可以看出,传入形参cls的值即为调用该方法的类。如果额外传入对象或类名称,会引发类型错误,因为类方法只接受一个额外的位置参数。


a.foo3("小熊猫")
A.foo3("小熊猫")
# a.foo3(a, "小熊猫") # TypeError: foo3() takes 2 positional arguments but 3 were given
# A.foo3(A, "小熊猫") # TypeError: foo3() takes 2 positional arguments but 3 were given
b.foo3("大熊猫")
B.foo3("大熊猫")

@staticmethod与@classmethod的具体用法对比

@staticmethod与@classmethod的具体用法对比

共同点:

@staticmethod和@classmethod均支持直接通过类名.方法名()进行调用。

主要区别:

  • 从使用角度看,@staticmethod不需要self(实例)或cls(类)参数,行为类似于普通函数。@classmethod同样不需要self,但第一个参数必须是cls,用于表示所属类。
  • 若在@staticmethod中需要访问类的属性或方法,只能直接通过类名.属性名或类名.方法名访问。
  • @classmethod由于持有cls参数,可以灵活调用类的属性、类方法或实例化对象,从而避免硬编码,提高代码的可维护性。

class A(object):
 a = 'a'
 @staticmethod
 def foo1(name):
 print('hello foo1', name, A.a)
 print("hello foo4 ", B.foo2(B, "小熊猫"))
 def foo2(self, name):
 print('hello foo2', name, self.a)
 @classmethod
 def foo3(cls, name):
 print('hello foo3', name, cls.a)
 print("hello foo5", cls().foo2(name))
 print("hello foo6", cls().foo1(name))
class B(A):
 a = 'b'
 @staticmethod
 def foo1(name):
 print('subclass B, hello', name, B.a)
 def foo2(self, name):
 print('subclass B, hello', name, self.a)
 @classmethod
 def foo3(cls, name):
 print('subclass B, hello', name, cls.a)

重点应关注@staticmethod和@classmethod在调用本类或其他类的函数和属性时的行为差异。

示例1分析

示例1分析:

关键在于第二句subclass B,hello 小熊猫 b。在调用B.foo2(B, “小熊猫”)时,执行了B类型下的foo2()方法。由于该方法无返回值,因此下一句输出为hello foo4 None。


a = A()
a.foo1("小熊猫")
# 输出
hello foo1 小熊猫 a
subclass B, hello 小熊猫 b
hello foo4 None

示例2分析

示例2分析:


a.foo3("小熊猫")
# 输出
hello foo3 小熊猫 a
hello foo2 小熊猫 a
hello foo5 None
hello foo1 小熊猫 a
subclass B, hello 小熊猫 b
hello foo4 None
hello foo6 None

补充说明:self与cls的区别

补充说明:下面进一步探讨Python中self和cls的区别。

1、self表示具体的实例对象。如果使用@staticmethod,则可以忽略self,将方法视为普通函数使用。

2、cls表示类本身。


>>> class A(object):
    def foo1(self):
      print "Hello",self
    @staticmethod
    def foo2():
      print "hello"
    @classmethod
    def foo3(cls):
      print "hello",cls

>>> a = A()
>>> a.foo1()     #最常见的调用方式,但与下面的方式相同
Hello <__main__.A object at 0x9f6abec>
>>> A.foo1(a)     #这里传入实例a,相当于普通方法的self
Hello <__main__.A object at 0x9f6abec>
>>> A.foo2()     #这里,由于静态方法没有参数,故可以不传东西
hello
>>> A.foo3()     #这里,由于是类方法,因此,它的第一个参数为类本身。
hello <class '__main__.A'>

>>> A         #可以看到,直接输入A,与上面那种调用返回同样的信息。
<class '__main__.A'>

3、更重要的是,类实例化时先调用__new__方法返回实例对象,该实例对象即作为__init__方法的第一个参数self,因此self本质上是__new__的返回值。

总结

总结

至此,关于Python中self与cls区别及装饰器用法的介绍已完成。如需了解更多相关内容,请搜索本站过往文章或继续浏览后续文章。感谢支持!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。