首页 > 其他分享 > 类里面静态方法(@staticmethod),类方法(@classmethod)和实例方法(self)的使用与区别

类里面静态方法(@staticmethod),类方法(@classmethod)和实例方法(self)的使用与区别

时间:2023-10-13 09:44:40浏览次数:38  
标签:静态方法 classmethod self month 实例 year day def

前言

python 类里面常用的方法有3个:静态方法(@staticmethod),类方法(@classmethod)和实例方法(self)
本篇讲解这3种方法在使用上有什么区别。

函数

先从函数说起,方法跟函数是有区别的,经常有人容易混淆,函数定义是def 关键字定义(外面没class)

def fun():
    a = "hello"
    return a

# 函数调用
res = fun()
print(res)

函数调用使用函数名称后面加括号就能调用了

实例方法(self)

类里面的方法定义也是用def 关键字,注意在类里面叫方法了,不叫函数,定义的方法默认在括号里面加一个self参数。
self 是类本身的实例对象,所以在看到def 定义的方法括号后面有self参数的叫实例方法。

class A(object):
    count = 0

    def fun(self):
        b = "world"
        return b

# A类不能直接调用fun
# print(A.fun())
a = A()
print(a.fun())

前面https://www.cnblogs.com/yoyoketang/p/15151723.html讲属性的时候说到过A类的属性和A()实例对象属性是不一样的。
fun()里面带了self参数,那么它是实例方法,也就是A()实例对象的方法了,所以必须先实例化A()才能调用此方法。

静态方法(@staticmethod)

我们可以在函数里面写一个类

def fun():
    a = "hello"
    
    class A(object):
        count = 0
    
        def fun(self):
            b = "world"
            return b
    return A

于是会想到,在类里面是不是也可以写一个函数呢?于是就有了静态方法(@staticmethod),静态方法的出现就是为了在类里面可以写一个函数,当普通的函数去调用。
定义静态方法需使用@staticmethod装饰器,并且括号后面不需要self参数了。

class A(object):
    count = 0

    def fun(self):
        b = "world"
        return b

    @staticmethod
    def start():
        print("start-----")

# 不用实例化也能调用
A.start()
# 实例化也能调用
a = A()
a.start()

静态方法不需要实例化可以直接调用,实例化后也能调用,可以理解成函数。

类方法(@classmethod)

类里面有2个概念,属性和方法。
前面讲到A类和A()实例对象的属性是不一样的,比如

  • A类只要count属性
  • A()实例对象的属性是__init__里面的age和name,并且包含A类属性count
class A(object):
    count = 0

    def __init__(self):
        self.age = 18
        self.name = "yoyo"
# A只有count属性
print(A.count)

# A() 实例化对象
a = A()
print(a.count)
print(a.name)
print(a.age)

既然已经知道了A类的属性和A()实例对象属性是不一样的,再回到前面的实例方法概念上,实例方法是A()实例对象的方法。
既然A()实例对象有实例方法,那么A类当然也有类方法的概念了,于是可以在方法上加上@classmethod装饰器声明它是类方法,并且括号第一个参数cls是指类本身

class A(object):
    count = 0

    def fun(self):
        b = "world"
        return b

    @staticmethod
    def start():
        print("start-----")

    @classmethod
    def create(cls):
        print("create--------")

# 不需要实例化,类名称直接调用类方法
A.create()
# 实例化也能调用类方法
a = A()
a.create()

类方法使用场景

实例方法和静态方法小伙伴们应该是经常用的,类方法这个概念本身比较难懂,就算看懂了也不知道如何用到具体场景上,在网上搜到一个案例讲解的挺好的。
看下面的定义的一个时间类:

class DataTest(object):
    day = 0
    month = 0
    year = 0

    def __init__(self, year=0, month=0, day=0):
        self.day = day
        self.month = month
        self.year = year

    def out_date(self):
        print("year :", self.year)
        print("month :", self.month)
        print("day :", self.day)

t = DataTest(2021, 8, 18)
t.out_date()   

输出:

year : 2021
month : 8
day : 18

如果用户输入的是 "2016-8-1" 这样的字符格式,那么就需要调用Date_test 类前做一下处理:

string_date = '2018-8-18'
year, month, day = map(int, string_date.split('-'))
s = DataTest(year, month, day)
print(s.out_date())

先把‘2018-8-18’ 分解成 year,month,day三个变量,然后转成int,再调用DataTest(year, month, day) 也很符合期望。
那我可不可以把这个字符串处理的函数放到 DateTest 类当中呢?
那么@classmethod 就开始出场了

class DataTest(object):
    day = 0
    month = 0
    year = 0

    def __init__(self, year=0, month=0, day=0):
        self.day = day
        self.month = month
        self.year = year

    def out_date(self):
        print("year :", self.year)
        print("month :", self.month)
        print("day :", self.day)

    @classmethod
    def get_data(cls, string_date):
        """处理'2018-8-18'字符格式"""
        year, month, day = map(int, string_date.split('-'))
        return cls(year, month, day)

定义一个get_data类方法,处理完字符串后返回这个类的实例对象

r = DataTest.get_data('2018-8-18')
r.out_date()

这样同样可以达到实例化的效果,于是就兼容了前面的代码了
参考资料https://www.zhihu.com/question/20021164

标签:静态方法,classmethod,self,month,实例,year,day,def
From: https://www.cnblogs.com/xingyaowuhen/p/17761173.html

相关文章

  • Java8新特性之接口的默认方法和静态方法(四)
    1.背景介绍在Java8之前,接口中定义的方法都是抽象方法,即默认都是被publicabstract修饰的;但从Java8开始,允许在接口中定义带有方法体的默认方法和静态方法;publicclassInterfaceTest{publicstaticvoidmain(String[]args){}}interfaceInterfaceA{/*......
  • 为什么 CSS flex 布局中没有 `justify-items` 和 `justify-self`?
    为什么CSSflex布局中没有justify-items和justify-self?为什么在CSSflex布局中存在align-items和align-self,却没有justify-items和justify-self呢?要解答这个问题,首先需要理解主轴(mainaxis)和交叉轴(crossaxis)之间的差异。1.主轴和交叉轴的区别在没有折行的情况......
  • Implicit Autoencoder for Point-Cloud Self-Supervised Representation Learning论文
    ImplicitAutoencoderforPoint-CloudSelf-SupervisedRepresentationLearning2023ICCV*SimingYan,ZhenpeiYang,HaoxiangLi,ChenSong,LiGuan,HaoKang,GangHua,QixingHuang*;ProceedingsoftheIEEE/CVFInternationalConferenceonComputerVision......
  • 论文阅读:Semi-supervised point cloud segmentation using self-training with label
    Semi-supervisedpointcloudsegmentationusingself-trainingwithlabelconfidencepredictionLi等人(2021b)基于伪标签置信度预测的半监督分割方法,额外设计判别网络(discriminatornetwork),该网络目标是区分预测结果和真实标注,并对无标注点云的预测结果输出置信度预测,对判别网络......
  • 静态方法不依赖实例对象的调用例题
    publicclassNull{publicstaticvoidsmile(){System.out.println("haha");}publicstaticvoidmain(String[]args){((Null)null).smile();}} 问代码之后之后,能否正常打印? 答案:是可以的,打印“haha” 解释:由于静态方法......
  • 面向对象 静态方法和动态方法 ;静态更先进因为新建和被调用时不需要传self
    展示动态方法 需要加self#A.py调用B的制作伞和扇子fromBimportHandmadeclassWeather:def__init__(self,type):self.type=typedefaction(self):f=Handmade.make_fan(self)u=Handmade.make_umbrella(self)pri......
  • self
    自我介绍哪里人准备在长沙吗我在本科时候,每年最具幸福感的城市排名长沙都榜上,之前也不太清楚世界有这么大去年跟家里人有去长沙玩过两天,岳麓山,烟火气息要比我呆过的地方更弄一些。生活压力来说我感觉也不会那么的大,如果能在长沙的话那是很好的选择。本科是南京工......
  • 论文解读:CrossPoint: Self-Supervised Cross-Modal Contrastive Learning for 3D Poin
    CrossPoint:Self-SupervisedCross-ModalContrastiveLearningfor3DPointCloudUnderstanding本文提出一种简单的跨模态3维—2维区域对应模块,分别将点云模态和图像模态提取的特征向量重新投影到一个公共的特征空间中,并基于最大化与模态无关的互信息的思想设计对比学习损失......
  • OpenLDAP:使用Self Service Password管理用户密码
    安装dockeryum-yinstalldocker拉取镜像dockerpullgrams/ltb-self-service-password编辑配置文件<?php#==============================================================================#LTBSelfServicePassword##Copyright(C)2009ClementOUDOT#Co......
  • python入门基础(14)--类的属性、成员方法、静态方法以及继承、重载
    上一篇提到过类的属性,但没有详细介绍,本篇详细介绍一下类的属性一、类的属性方法是用来操作数据的,而属性则是建模必不的内容,而且操作的数据,大多数是属性,比如游戏中的某个boss类,它的生命值就是属性(不同级别的boss,有不同的生命值),被攻击方法(不同的攻击,伤害值不同),当boss被攻击......