Python 静态方法(@staticmethod)
静态方法是定义在类体内部的函数,用 @staticmethod 标记。调用时不会自动传入 self(实例) 或 cls(类),因此不绑定某一具体实例或类对象。
- 仍可通过
类名.静态方法(...)或实例.静态方法(...)调用(后者不会把实例当作第一个参数传入)。 - 若需要读类属性或实例属性,必须在方法内显式写
类名.属性或把对象作为参数传入;不能像实例方法那样依赖self.x,也不能像类方法那样依赖cls.x。
适合把与类概念相关、但逻辑上不依赖实例状态的工具函数收拢在类命名空间下,便于组织代码(与模块级函数相比,多了一层「归属」)。与 类与对象、self 变量 对照阅读更清晰。
为什么需要静态方法?
例如把字符串、列表、元组相关的工具按主题放进不同类,命名空间更清晰:
python
class ListUtils:
@staticmethod
def reverse(lst):
return lst[::-1]
@staticmethod
def clear(lst):
lst.clear()
class StringUtils:
@staticmethod
def reverse(s):
return s[::-1]
@staticmethod
def upper(s):
return str(s).upper()需要时调用 ListUtils.reverse(...)、StringUtils.upper(...) 即可。若逻辑与类完全无关,用模块级函数同样合理,按团队风格选择。
两种写法
1. 装饰器 @staticmethod(推荐)
python
class MathUtils:
@staticmethod
def multiply(a, b):
return a * b
print(MathUtils.multiply(10, 5)) # 502. 内置函数 staticmethod(...)
把普通函数包装后赋给类属性,效果类似:
python
class StringUtils:
def to_uppercase(s):
return str(s).upper()
StringUtils.upper = staticmethod(StringUtils.to_uppercase)
print(StringUtils.upper("Python")) # PYTHON若把 to_uppercase 当成实例方法去调用(未加 staticmethod),解释器会传入 self,容易出现「多传了一个参数」的错误:
python
su = StringUtils()
try:
print(su.to_uppercase("Python"))
except TypeError as e:
print(e) # takes 1 positional argument but 2 were given未包装时,从类名直接调用 StringUtils.to_uppercase("Python") 可以,因为只传入一个参数。
静态方法、类方法、实例方法对比
| 实例方法 | 类方法 @classmethod | 静态方法 @staticmethod | |
|---|---|---|---|
| 第一个参数 | self(实例) | cls(类) | 无默认绑定 |
| 典型用途 | 读写实例状态 | 工厂方法、需要类对象本身 | 逻辑放在类下但不依赖 self/cls |
| 访问实例属性 | self.x | 需先有实例或显式传入 | 须通过参数或其它方式 |
| 访问类属性 | 类名.x 或 self.x(查找链) | cls.x | 类名.x(显式) |
示例:
python
class Test:
x = 10
@classmethod
def foo(cls):
print(cls.x)
@staticmethod
def bar():
print(Test.x) # 须写类名;不能写未限定的 x
Test.foo()
Test.bar()输出:
text
10
10实例方法需要 self,可访问绑定到该实例的属性及类属性(按查找规则):
python
class Test:
x = 10
def func(self):
print(type(self))
print(self.x)小结
@staticmethod:不自动接收self/cls,更像挂在类上的普通函数。- 需要类或实例时,用类名、参数或改用
@classmethod/ 实例方法。 - 日常优先用装饰器语法;
staticmethod(...)多用于动态挂载等少见场景。
参考
- 内置函数 staticmethod
- 描述符 HowTo(理解
staticmethod与绑定机制,进阶阅读)