python面向对象-类方法

概述

同类属性相同,类也可以有类方法

可以被继承

应用场景

如果类中的方法,只需要访问类属性,那么就 可以定义 成类方法。

语法

class 类:
    @classmethod
    def 方法名(cls):
        pass
  1. 方法上要有 @classmethod 修饰
  2. 方法的第一个形参是 cls(class的缩写,规范),表示 类本身
  3. 可以通过 cls.类属性名 访问类属性

调用

  1. 通过 类名.方法名() 可以直接调用
  2. 也可以通过 对象.方法名() 调用
  3. 调用时,不需要传参给 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,所以:

  1. 不能访问实例属性、实例方法
  2. 可以访问类属性、类方法

参考:

https://blog.csdn.net/qq_31780525/article/details/72639491
https://blog.csdn.net/u014745194/article/details/73392550


原文出处:/show_1EF2EdDaBBD5.html