Python面向对象 | 类方法 classmethod

 

类方法:必须通过类的调用,而且此方法的意义:就是对类里面的变量或者方法进行修改添加。

例一个商店,店庆全场八折,代码怎么写呢?

class Goods:
    __discount = 0.8  # 折扣

    def __init__(self,name,origin_price):
        self.name = name
        self.__price = origin_price

    @property
    def price(self):
        return self.__price * Goods.__discount

apple = Goods('apple',5)
banana = Goods('banana',8)
print(apple.price)
print(banana.price)


'''
执行输出:
4.0
6.4
'''

现在折扣变了,店庆结束,恢复原价。如何修改__discount变量呢?不能这么写。

Goods._Goods__discount = 1

怎么办呢?定义一个方法,修改属性

class Goods:
    __discount = 0.8
    def __init__(self,name,origin_price):
        self.name = name
        self.__price = origin_price

    @property
    def price(self):
        return self.__price * Goods.__discount

    def change_discount(self,new_discount):     # 修改折扣
        Goods.__discount = new_discount         #修改了全局的

apple = Goods('apple',5)
banana = Goods('banana',8)

apple.change_discount(1)                        #修改折扣为1
print(apple.price)
print(banana.price)

'''
执行输出:
5
8
'''

但是修改类静态变量,不需要实例化才对啊。如果要改变折扣是全场的事情不牵扯到一个具体的物品 所以不应该使用对象来调用这个方法。

 

类函数(@classmethod):即类方法, 更关注从类中调用方法, 而不是在实例中调用方法

不依赖对象的方法 就应该定义成类方法,类方法可以任意操作类中的静态变量

class Goods:
    __discount = 0.8  # 折扣
    def __init__(self,name,origin_price):
        self.name = name
        self.__price = origin_price  # 原价

    @property
    def price(self):  # 价格
        return self.__price * Goods.__discount

    @classmethod
    def change_discount(self,new_discount):
        Goods.__discount = new_discount

Goods.change_discount(1)  # 类方法 可以直接被类调用 不需要默认传对象参数 只需要传一个类参数就可以了

apple = Goods('apple',5)
banana = Goods('banana',8)

print(apple.price)
print(banana.price)

'''
执行输出:
5
8
'''

练习题

假设我有一个学生类和一个班级类,想要实现的功能为:

  1. 执行班级人数增加的操作、获得班级的总人数;
  2. 学生类继承自班级类,每实例化一个学生,班级人数都能增加;
  3. 最后,我想定义一些学生,获得班级中的总人数。
class C:
    count = 0
    def __init__(self):
        C.cou()

    @classmethod
    def cou(cls):
        cls.count += 1

obj = C()
obj = C()
obj = C()
obj = C()
obj = C()
obj = C()
obj = C()
obj = C()
obj = C()
obj = C()
obj = C()
print(C.count)    #  11
View Code

思考:这个问题用类方法做比较合适,为什么?因为我实例化的是学生,但是如果我从学生这一个实例中获得班级总人数,在逻辑上显然是不合理的。同时,如果想要获得班级总人数,如果生成一个班级的实例也是没有必要的。

class Student:
    __num = 0

    def __init__(self, name, age):
        self.name = name
        self.age = age
        Student.addNum()  # 写在__new__方法中比较合适,但是现在还没有学,暂且放到这里

    @classmethod
    def addNum(cls):
        cls.__num += 1

    @classmethod
    def getNum(cls):
        return cls.__num


a = Student('Tony', 18)
b = Student('John', 19)
c = Student('Linda', 20)
print(Student.getNum())         # 3

猜你喜欢

转载自www.cnblogs.com/Summer-skr--blog/p/11801434.html