首先还是我们熟悉的八股文:
类方法 就是针对 类对象 定义的方法
语法如下
- @classmethod
- def 类方法名(cls):
- pass
'运行
类方法需要用 修饰器 @classmethod 来标识,告诉解释器这是一个类方法
类方法的 第一个参数 应该是 cls
由 哪一个类 调用的方法,方法内的 cls 就是 哪一个类的引用
这个参数和 实例方法 的第一个参数是 self 类似
提示 使用其他名称也可以,不过习惯使用 cls
通过 类名. 调用 类方法,调用方法时,不需要传递 cls 参数
在方法内部
可以通过 cls. 访问类的属性
也可以通过 cls. 调用其他的类方法
示例需求
定义一个 工具类
每件工具都有自己的 name
需求 —— 在 类 封装一个 show_tool_count 的类方法,输出使用当前这个类,创建的对象个数

- @classmethod
- def show_tool_count(cls):
- """显示工具对象的总数"""
- print("工具对象的总数 %d" % cls.count)
'运行
在类方法内部,可以直接使用
cls访问 类属性 或者 调用类方法
类方法:通过@classmethod装饰器实现
类方法和普通方法的区别:
类方法只能访问类变量,不能访问实例变量
直接看代码:
- '''
- 类方法:通过@classmethod装饰器实现
- 类方法和普通方法的区别:
- 类方法只能访问类变量,不能访问实例变量
- (刨根问底)问题1:为什么类方法中不能够访问实例变量?
- 答:因为类方法中的self并不是和创建的对象所绑定--简单点来说,因为self这个参数接收的不是实例本身,而是指向类本身
- 注:当你先写装饰器,在定义方法,会发现方法后的()内是cls 而不是self,这就印证了上面的说明!!
- 问题2:类方法到底有啥用?
- '''
- class Student:
- def __init__(self,name):
- self.name=name
-
- @classmethod
- def show(cls):
- print('学生的名字为:%s'%cls.name)
-
-
- s1=Student('小明')
- s1.show()
![]()
(刨根问底)问题1:为什么类方法中不能够访问实例变量?
答:因为类方法中的self并不是和创建的对象所绑定--简单点来说,因为self这个参数接收的不是实例本身,而是指向类本身
- class Student:
- name='dog1'
- def __init__(self,name):
- self.name=name
-
- @classmethod
- def show(self):
- print(self)
- print('学生的名字为:%s'%self.name)
-
-
- s1=Student('小明')
- s1.show()
'运行

你会发现类方法中的self指向的是类本身,而不是实例对象
- class Student:
- name='dog1'
- def __init__(self,name):
- self.name=name
-
- @classmethod
- def show(self):
- print(self)
- print('学生的名字为:%s'%self.name)
-
-
- s1=Student('小明')
- s1.show()
- print(Student)
'运行

注:当你先写装饰器,在定义方法,会发现方法后的()内是cls 而不是self,这就印证了上面的说明!!
- class Student2:
- num=0
- def __init__(self,name):
- self.name=name
- self.num+=1
- print(self.name,self.num)
-
- s2=Student2('小李')
- s3=Student2('小红')
'运行

问题3:为什么num一直是1?
答:因为这里对num+1是针对的每个新创建的实例对象,而不是针对于整个大类而言
问题4:如何解决这个问题?
答:将Self换成类本身即可!!
- class Student2:
- num=0
- def __init__(self,name):
- self.name=name
- Student2.num+=1
- print(self.name,self.num)
-
- s2=Student2('小李')
- s3=Student2('小红')
'运行

但是这个代码有个bug!当你不创建对象,直接对在外部调用num时也可以使数量+1
- class Student2:
- num=0
- def __init__(self,name):
- self.name=name
- Student2.num+=1
- print(self.name,self.num)
-
- s2=Student2('小李')
- s3=Student2('小红')
- Student2.num+=1
- print(Student2.num)
'运行

问题5:如何解决这个问题?
答:可以使用类方法避免这个问题!
- class Student2:
- #将num变成一个私有变量
- __num=0
- def __init__(self,name):
- self.name=name
- #Student2.num+=1
- Student2.gain_num()
- print(self.name,self.__num)
-
- @classmethod
- def gain_num(cls):
- cls.__num+=1
-
- s2=Student2('小李')
- s3=Student2('小红')
- #Student2.num+=1
- print(Student2.num)

最终的代码如下:有小伙伴们找到bug可以和我交流一下!!
- class Student2:
- #将num变成一个私有变量
- __num=0
- def __init__(self,name):
- self.name=name
- #Student2.num+=1
- Student2.__gain_num()
- print(self.name,self.__num)
-
- @classmethod
- def __gain_num(cls):
- cls.__num+=1
-
- s2=Student2('小李')
- s3=Student2('小红')
'运行