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

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

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()

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

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)

Python面向对象 | 类方法 classmethod的更多相关文章

  1. python 面向对象 类方法,静态方法,property

    property 内置装饰器函数 只在面向对象使用 把方法当初属性使用(方法不加参数) 例子: class Rectangle: def __init__(self,long,wide,color): ...

  2. Python面向对象静态方法,类方法,属性方法

    Python面向对象静态方法,类方法,属性方法 属性: 公有属性 (属于类,每个类一份) 普通属性 (属于对象,每个对象一份) 私有属性 (属于对象,跟普通属性相似,只是不能通过对象直接访问) 方法: ...

  3. Python面向对象 --- 新旧式类、私有方法、类属性和类方法、静态方法

    一.Python面向对象中的新旧式类 1)新式类(推荐使用):在定义类时,类后边括号里要继承基类(object).在python3.x中若没有指定父类,会默认使用的是object作为基类:在pytho ...

  4. Python面向对象之类属性类方法静态方法

    类的结构 实例 使用面向对象开发时,第一步是设计类: 当使用 类名() 创建对象时,会自动执行以下操作: 1.为对象在内存中分配空间--创建对象: 2.为对象的属性 设置初始值--初始化方法(init ...

  5. Python - 静态方法@staticmethod和类方法classmethod

    传送门 https://github.com/jackfrued/Python-100-Days/blob/master/Day01-15/Day09/%E9%9D%A2%E5%90%91%E5%AF ...

  6. Python面向对象05 /私有成员、类方法、静态方法、属性、isinstance/issubclass

    Python面向对象05 /私有成员.类方法.静态方法.属性.isinstance/issubclass 目录 Python面向对象05 /私有成员.类方法.静态方法.属性.isinstance/is ...

  7. python 面向对象专题(五):私有成员、类方法、静态方法、属性、isinstance/issubclass

    https://www.cnblogs.com/liubing8/p/11325421.html 目录 Python面向对象05 /私有成员.类方法.静态方法.属性.isinstance/issubc ...

  8. 【面试必问】python实例方法、类方法@classmethod、静态方法@staticmethod和属性方法@property区别

    [面试必问]python实例方法.类方法@classmethod.静态方法@staticmethod和属性方法@property区别 1.#类方法@classmethod,只能访问类变量,不能访问实例 ...

  9. Python的3个方法:静态方法(staticmethod),类方法(classmethod)和实例方法

    Python的方法主要有3个,即静态方法(staticmethod),类方法(classmethod)和实例方法,如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...

随机推荐

  1. vertica单节点故障恢复 Startup Failed, ASR Required

    测试环境的vertica是单节点的,无法做到故障自动恢复,需要手工处理.案例如下: 发现5433端口连接不上,vertica挂了,手工运行admintools,重新启动vertica,仍然失败,提示: ...

  2. Java中json使用与问题汇总

    一.JSON 解析类库 FastJson: 阿里巴巴开发的 JSON 库,性能十分优秀. 在maven项目的pom文件中以下依赖 <dependency> <groupId>c ...

  3. RGB灯

    robotbit扩展板4个rgb灯,r-红,g-绿,b-蓝,值为0~255,可模拟出256*256*256种颜色. from microbit import * import neopixel r = ...

  4. 动态引用存储——集合&&精确的集合定义——泛型

    1,集合宏观理解 1.1,为什么引入集合? 对于面向对象的语言来说,操作对象的功能不可或缺. 为了方便对对象进行操作和处理,就必须要对对象进行暂时的存储.[数据最终存在数据库里] 使用数组来存储对象的 ...

  5. Docker私有云管理平台————Docker Shipyard

    一.shipyard中文版安装(CentOS) 注:本文安装操作均在root用户下,安装前需先安装Docker (传送门) 下载所需docker镜像 docker pull rethinkdb doc ...

  6. MySQL数据库 : 高级查询

    根据某个字段删除重复的数据, 只保留一条: 比如uuid字段有重复的, 需要只保留一条数据, 让uuid字段不能重复, 则首先 group by uuid 查出所有数据的id最小的那条数据,作为dt表 ...

  7. kvm虚拟机vnc配置

    通过vnc方式访问虚拟主机上的KVM虚拟机 通过虚拟主机的IP地址与端口进行访问 1.  修改qemu.conf # vi /etc/libvirt/qemu.conf vnc_listen = &q ...

  8. 3-awk

    1.输出双引号:awk '{print "\""}'        #放大:awk '{print "  \"  "}'使用“”双引号把一个 ...

  9. pom.xml管理jar包——安全性框架配置文件

    <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> &l ...

  10. EF自动创建数据库步骤之三(自定义数据库初始器)

    EF自动创建数据库需要我们告诉数据库如何进行初始化:如创建表后是否需要插入一些基础数据,是否 需要创建存储过程.触发器等.还有就是EF有三种初始化方式(参见下面三个类): DropCreateData ...