概述
同类属性相同,类也可以有类方法
可以被继承
应用场景
如果类中的方法,只需要访问类属性,那么就 可以定义 成类方法。
语法
class 类:
@classmethod
def 方法名(cls):
pass
- 方法上要有
@classmethod修饰 - 方法的第一个形参是
cls(class的缩写,规范),表示 类本身 - 可以通过
cls.类属性名访问类属性
调用
- 通过
类名.方法名()可以直接调用 - 也可以通过
对象.方法名()调用 - 调用时,不需要传参给
cls,python解释器会自动传递类本身
案例
在互联网程序中,有实时在线人数,在一个平台中,在线人数只有一个,所以没有实例化对象的必要性。
只需要在类中定义 类属性 “总共人数”,通过类方法对“总共人数”进行增加、减少
实现一:公共类属性(缺点)
class UserCount:
num = 0
缺点
应该 来一个人访问就加1,离开一个人就减1
而 不应直接修改值,甚至可以赋值 负数,这是不正确的
UserCount.num = -200
实现二:私有类属性
在类中定义 私有 类属性 “总共人数”,通过 类方法 对“总共人数”进行增加、减少。
#coding=utf-8
class UserCount:
__num=0
@classmethod
def add(cls):
cls.__num += 1
@classmethod
def minus(cls):
cls.__num -= 1
@classmethod
def get(cls):
return cls.__num
调用
UserCount.add()
print(UserCount.get())
UserCount.add()
print(UserCount.get())
UserCount.add()
print(UserCount.get())
UserCount.add()
print(UserCount.get())
UserCount.minus()
print(UserCount.get())
#通过对象也可以访问
uc=UserCount()
uc.add()
print(uc.get())
发现 bug
如果一直调用 minus() 方法, __num 会成 负数,所以要加判断
解决 bug
@classmethod
def minus(cls):
if cls.__num > 0:
cls.__num -= 1
优化代码
在上面的代码中,在执行 add() 方法、minus() 方法后,还需要调用 get() 方法才能返回总数,比较繁琐
,我们对其进行优化,不需要调用get()方法就能打印出总数
@classmethod
def add(cls):
cls.__num += 1
return cls.get()
@classmethod
def minus(cls):
if cls.__num > 0:
cls.__num -= 1
return cls.get()
调用
print(UserCount.add())
print(UserCount.add())
print(UserCount.add())
print(UserCount.minus())
print(UserCount.minus())
print(UserCount.minus())
print(UserCount.minus())
print(UserCount.minus())
print(UserCount.minus())
print(UserCount.minus())
print(UserCount.minus())
print(UserCount.get())
注意:
如果“总共人数”是公有的,在外部可能会给该属性设置不正确的值,比如设置字符串、或者负数。
所以要将其设置为私有,通过相应的类方法操作该属性
应用场景
在python类库中, datetime 类的 today() 方法就是类方法,源码如下:
@classmethod
def today(cls):
"Construct a date from time.time()."
t = _time.time()
return cls.fromtimestamp(t)
总结
在类方法的形参中,只有表示类本身的 cls,没有表示实例本身的 self,所以:
- 不能访问实例属性、实例方法
- 可以访问类属性、类方法
参考:
https://blog.csdn.net/qq_31780525/article/details/72639491
https://blog.csdn.net/u014745194/article/details/73392550