Python中@staticmethod和@classmethod的区别

Python中@staticmethod和@classmethod的区别

技术背景

在Python的面向对象编程中,@staticmethod@classmethod是两个重要的装饰器,它们可以改变方法的调用方式和行为。理解它们的区别对于编写高效、可维护的Python代码至关重要。

实现步骤

实例方法

实例方法是最常见的方法类型,它的第一个参数通常是self,代表类的实例。实例方法可以访问和修改实例的属性。

1
2
3
4
5
6
7
class A(object):
def foo(self, x):
print(f"executing foo({self}, {x})")

a = A()
a.foo(1)
# 输出: executing foo(<__main__.A object at 0xb7dbef0c>, 1)

类方法

类方法使用@classmethod装饰器,它的第一个参数是cls,代表类本身。类方法可以通过类名或实例名调用。

1
2
3
4
5
6
7
8
9
10
11
class A(object):
@classmethod
def class_foo(cls, x):
print(f"executing class_foo({cls}, {x})")

a = A()
a.class_foo(1)
# 输出: executing class_foo(<class '__main__.A'>, 1)

A.class_foo(1)
# 输出: executing class_foo(<class '__main__.A'>, 1)

静态方法

静态方法使用@staticmethod装饰器,它没有隐含的第一个参数,既不是self也不是cls。静态方法可以通过类名或实例名调用。

1
2
3
4
5
6
7
8
9
10
11
class A(object):
@staticmethod
def static_foo(x):
print(f"executing static_foo({x})")

a = A()
a.static_foo(1)
# 输出: executing static_foo(1)

A.static_foo('hi')
# 输出: executing static_foo(hi)

核心代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class MyClass:
def method(self):
return 'instance method called', self

@classmethod
def class_method(cls):
return 'class method called', cls

@staticmethod
def static_method():
return 'static method called'

obj = MyClass()
print(obj.method())
print(obj.class_method()) # MyClass.class_method()
print(obj.static_method()) # MyClass.static_method()

输出:

1
2
3
('instance method called', <__main__.MyClass object at 0x100fb3940>)
('class method called', <class '__main__.MyClass'>)
static method called

最佳实践

类方法用于替代构造函数

1
2
3
4
5
6
7
8
9
10
11
12
class Person(object):
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name

@classmethod
def get_person(cls, first_name):
return cls(first_name, "")

person = Person.get_person("John")
print(person.first_name) # 输出: John
print(person.last_name) # 输出:

静态方法用于逻辑分组

1
2
3
4
5
6
7
8
9
10
class Point:
def __init__(self, x, y):
self.x = x
self.y = y

@staticmethod
def angle(x, y):
return atan(y, x)

angle = Point.angle(3, 2)

常见问题

如何选择使用@staticmethod还是@classmethod

  • 如果方法需要访问类级别的属性或方法,使用@classmethod
  • 如果方法独立运行,不与类的其他组件交互,使用@staticmethod

静态方法和类方法在继承中的区别

  • 静态方法的定义在继承中是不可变的,子类无法利用自身的特性。
  • 类方法的定义在继承中会遵循子类,可以被子类重写并利用子类的特性。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Parent:
_class_name = "Parent"

@staticmethod
def print_name():
print(Parent._class_name)

class Child(Parent):
_class_name = "Child"

@staticmethod
def print_name():
print(Child._class_name)

Parent.print_name() # 输出: Parent
Child.print_name() # 输出: Child

class Parent:
_class_name = "Parent"

@classmethod
def print_name(cls):
print(cls._class_name)

class Child(Parent):
_class_name = "Child"

Parent.print_name() # 输出: Parent
Child.print_name() # 输出: Child

Python中@staticmethod和@classmethod的区别
https://119291.xyz/posts/2025-05-09.difference-between-staticmethod-and-classmethod-in-python/
作者
ww
发布于
2025年5月9日
许可协议