Python类定义中的@classmethod(类方法)和@staticmethod(静态方法)的使用
之前的一篇博文详细讲解了什么函数装饰器(Python迭代器、生成器、装饰器的使用)。在类的定义中,我们也常常见到装饰器的使用,并且最常用的就是@classmethod,@staticmethod来装饰我们自定义类的函数(方法),这两个内置的装饰器是什么作用呢?
在讲解这两种方法前我们需要只要,一般我们在类当中定义的方法都是实例方法,定义中都需要带有self关键字,要使用实例方法,必须先把我们的类实例化才能使用。比如下面的个Dog类中的name方法。
1 2 3 4 5 6 7 8 9 | class Dog(): def __init__( self , name, age): self .name = name self .age = age def dogname( self ): print ( "我是一只狗,名叫{}" . format ( self .name)) dog1 = Dog( "阿黄" , 12 ) |
如果要使用实例方法dogname(),我们只能采用dog1.dogname()才能够使用。实例方法可以访问实例变量、类变量,使用时必须通过实例名来调用。
1、类方法(@classmethod)
什么叫做类方法呢?只要是在定义函数的时候在前面加上@classmethod那么接下来定义的这个函数就被称为类方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | class Dog(): dog_dict = { "大狗" : 12 , "二狗" : 11 , "三狗" : 20 } # 定义了一个类变量(一个字典),表示大狗有12只,二狗有11只,三狗有20只 def __init__( self , name, age): self .name = name self .age = age def dogname( self ): print ( "我是一只狗,名叫{}" . format ( self .name)) @classmethod def dog_number( cls ): number = 0 for item in cls .dog_dict.items(): number + = item[ 1 ] print ( '总共有{}只狗' . format (number)) dog1 = Dog( "阿黄" , 12 ) dog2 = Dog( "二黄" , 7 ) dog1.dog_number() Dog.dog_number() |
执行结果:
类方法不是因为具体的哪个实例而改变,因此在定义时必须使用cls(类变量)作为第一个参数(大家可以看成self的作用,只是它表示的是一个类)。既然这个方法是类方法,那我们自然可以采用类名.dog_number()来进行调用,也可以采用实例名.dog_number()来进行调用。类方法是可以访问类变量,当然也可以访问实例变量(不过需要传入参数self,并且在使用时需要把实例名传入函数中)。
2、静态方法(@staticmethod)
同样的在定义函数的时候在前面加上@staticmethod那么接下来定义的这个函数就被称为静态方法,静态方法不要求你强制传入任何参数(实例方法必须传入slef,类方法必须传入cls),因此这个函数对类变量和实例变量都是一无所知,你需要自己传入参数才能使用。调用的时候,可以使用实例名.方法名调用,或者类名.方法名调用。看例子
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 30 31 | class Dog(): dog_dict = { "大狗" : 12 , "二狗" : 11 , "三狗" : 20 } # 定义了一个类变量(一个字典),表示大狗有12只,二狗有11只,三狗有20只 def __init__( self , name, age): self .name = name self .age = age def dogname( self ): print ( "我是一只狗,名叫{}" . format ( self .name)) @classmethod def dog_number( cls ): number = 0 for item in cls .dog_dict.items(): number + = item[ 1 ] print ( '总共有{}只狗' . format (number)) @staticmethod def total_age(dogs): ''' 传入一个Dog实例的list,并计算这些狗的总年龄 ''' total = 0 for dog in dogs: total + = dog.age return total dog1 = Dog( "阿黄" , 12 ) dog2 = Dog( "二黄" , 7 ) print (dog1.total_age([dog1, dog2])) |
3、额外知识
1、类变量:是所有实例共享的,专属于这个类的,换句话说只要当前这个实例时属于A类,那么该实例就能使用A类的所有类变量。访问类变量得分情况,如果是在类方法中访问类变量,那么是使用 cls.类变量名 ;如果是在实例方法中访问类变量,使用 self.类变量名 。
2、除了常用的@classmethod和@staticmethod是常用的自定义类函数的装饰器,还有@property 也是常用的装饰类函数的装饰器,其作用是可以直接使用实例名.函数名来进行调用函数,不需要末尾加()了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南