Python中staticmethod和classmethod的作用与区别
本文深入解析Python中@staticmethod与@classmethod的区别。静态方法无需self和cls参数,适用于与类无关的工具函数;类方法接收cls参数,可访问类属性和方法,在继承场景中能避免硬编码,确保子类调用时获取正确的类上下文。
通常情况下,调用类中的方法需要先创建该类的实例对象,再通过实例调用方法。
若使用@staticmethod或@classmethod装饰器,则无需实例化对象,可直接通过“类名.方法名()”的方式调用。
这种机制有助于代码组织,将属于特定类的函数归置到该类中,同时保持命名空间的清晰整洁。
既然@staticmethod和@classmethod都支持直接通过类名调用,二者具体存在哪些差异?
从使用方式来看:
- @staticmethod装饰的方法不需要表示实例对象的self参数,也不需要表示类的cls参数,其调用形式与普通函数一致。
- @classmethod装饰的方法不需要self参数,但其第一个参数必须是指代当前类的cls参数。
若在@staticmethod中需要调用类的某些属性或方法,只能直接通过“类名.属性名”或“类名.方法名”的方式访问。
@classmethod由于持有cls参数,能够调用类的属性、类方法以及实例化对象等,从而避免代码中的硬编码问题。
为了深入理解,需明确实例方法、静态方法和类方法的定义:
class Demo(object):
def instance_method(self, your_para):
"""
this is an instance_method
you should call it like the follow:
a = Demo()
a.instance_method(your_para)
plus: in python, we denote 'cls' as latent para of Class
while 'self' as latent para of the instance of the Class
:param your_para:
:return:
"""
print("call instance_method and get:", your_para)
@classmethod
def class_method(cls, your_para):
"""
this is a class_method
you can call it like the follow:
method1:
a = Demo()
a.class_method(your_para)
method2:
Demo.class_method
plus: in python, we denote 'cls' as latent para of Class
while 'self' as latent para of the instance of the Class
:param your_para:
:return:
"""
print("call class_method and get:", your_para)
@staticmethod
def static_method(your_para):
"""
this is a static_method and you can call it like the
methods of class_method
:param your_para:
:return:
"""
print("call static_method and get:", your_para)
虽然调用类方法时未显式声明cls,但类本身会作为隐含参数传入,这与实例方法调用时隐式传入self(实例本身)的原理类似。
对于静态方法,通常将那些既与类状态无关、也与实例状态无关的函数定义为静态方法。例如,入口检查类的函数通常适合定义为静态方法。
类方法的独特优势体现在继承场景中:
class Fruit(object):
total = 0 # 这是一个类属性
@classmethod
def print_total(cls):
print('this is the ', cls, '.total:', cls.total, ' and its id: ', id(cls.total)) # cls是类本身,打印类属性total的值
print('this is the Fruit.total:', Fruit.total, 'and its id: ', id(Fruit.total))
print("=======================")
@classmethod
def set(cls, value):
cls.total = value
class Apple(Fruit):
pass
class Orange(Fruit):
pass
app1 = Apple()
app1.set(10)
app1.print_total()
Apple.print_total()
Fruit.set(2)
app1.print_total()
Fruit.print_total()
"""
output:
this is the <class '__main__.Apple'> .total: 10 and its id: 1355201264
this is the Fruit.total: 0 and its id: 1355200944
=======================
this is the <class '__main__.Apple'> .total: 10 and its id: 1355201264
this is the Fruit.total: 0 and its id: 1355200944
=======================
this is the <class '__main__.Apple'> .total: 10 and its id: 1355201264
this is the Fruit.total: 2 and its id: 1355201008
=======================
this is the <class '__main__.Fruit'> .total: 2 and its id: 1355201008
this is the Fruit.total: 2 and its id: 1355201008
=======================
"""
总结
以上就是本文的全部内容,希望这些解析对您的Python学习或工作有所帮助。感谢支持,如需了解更多相关内容,请查阅相关链接。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









