【PYTHON】浅谈Python中的类对象、实例对象、静态方法、类方法

0 引言

当我们在查看Python代码时,有时经常会遇到有下面这种代码,我们可能会很困惑,这些代码代表什么意思呢。这里我就我的理解,对类对象、实例方法切入,谈谈我对类方法和静态方法的理解。


class Test():
    var = "12345" #全局变量
    
    def __init__(self,name):
        self.name = name
    
    #该方法是类中的实例方法
    def run(self):
        print("I am running,{}".format(self.name))    

    @classmethod  #类方法的装饰器
    def fun_cls(cls,var):
        cls.var = var

    @staticmethod #静态方法的装饰器
    def fun_sta():
        print("This is in the static obj")
    
    @classmethod
    def getVar(cls):
        return cls.var

1 类对象和实例对象

查看上面的代码,我们可以对Test()类进行实例化,创建两个实例来查看。如下截图所示,对于实例对象t1和实例对象t2,他们分别是是类对象Test()的两个不同的别名,也就是指针引用。但是t1和t2的是两个不同的内存空间,从比较结果可以看出。截图中的Test()便是类对象,因为Python中一切皆对象,所以也就是说,该类在定义时,Python会在内存中开辟一块空间,用来存放类对象Test()的一些属性,包括类的变量或方法函数等,比如Test()中个var变量和fun_sta()等。实例对象是类对象的一个别名,但是不是说类对象实例对象就是类对象本身,他们之间有区别。实例对象对应着Test()类中方法的self关键字,而类对象则对应着Test()类中的cls关键字。


从上面的示意图我们可以看到实例对象和类对象之间的对应关系,创建了一个实例对象之后,就在内存中开辟了一个实例对象的内存空间块,里面存着的是实例对象的一些基本属性,这些基本属性是在类对象中的对应着self那部分,而不是对应着cls和静态方法那部分。当我们想要修改类对象中的var变量时,我们不能直接修改,但是我们可以间接修改var的值,但是这样并不是我们想要的,变量也想要有个名分,不是吗。我们可以通过如下这种方式进行间接修改var的值:t1.__class__.var = 23456。如下所示:


2 静态方法和类方法

2.1 类方法

当我们想要修改类对象中的属性(变量或者方法)时,我们不希望使用哪种间接的方式,而希望使用比较直接的方式,不要偷偷摸摸的改,想要光明正大的改。那么我们应该如何做呢?查看上面的代码,我们可以看到,我们可以直接在类中的方法上加一个语法糖,@classmethod,这是Python中的装饰器,我们给该方法加了一个装饰器,那么该方法就具有了该装饰器中所具有的的额外的功能。代码如下所示:


class Test():
    ...

    @classmethod  #类方法的装饰器
    def fun_cls(cls,var):
        cls.var = var

    @classmethod
    def getVar(cls):
        return cls.var

    ...

加了@classmethod语法糖之后,对应着括号中的参数也发生了变化,之前的普通的方法中传入的self,也就是说传入的参数是当前对应着的实例对象本身,而类方法所传入的对象则是当前类对象本身,也就是Test()本身。那么我们就可以将需要修改的变量通过类方法去直接修改实现,而不是通过间接的方式修改。这里举一个例子,代码如上所示,运行结果如下:


2.2 静态方法

静态方法在Python中,其实可以把它当做一个与当前类平行的函数,只不过我们将其放在了类中,也是为了方便管理和调用。这里用代码举例说明。


def test():
    print("this is in outer test!")

class Test():
    var = "12345" #全局变量
    
    def __init__(self,name):
        self.name = name
    
    def run(self):
        self.test()
        test()
    

    @staticmethod #静态方法的装饰器
    def test():
        print("This is in the static obj,inner test")
    

运行结果如下截图所示:从截图中我们可以看到,运行了run()方法之后,输出了两条打印,但是一条是类外边的,一条是类中的。因为有的时候我们可能需要使用一些函数来对一些数据做处理,但是该函数与该类并没有明显的逻辑关系。也就是说当我们在定义一个动物类的时候,但是我们相要计算动物的总数,但是动物总数和动物类本身并没有逻辑关系,本应该计算总数的函数应该写在函数外边,但是假如其他的类中也需要使用到计算总数的函数,但是有因为是不同的类,所以函数中的有些细节又不是一样,所以这个时候为了方便管理和调用,所以直接在类上加一个语法糖@staticmethod,使得该方法(函数)和当前类是一种平行关系,而不是包含关系。


3 后记

如果觉得我讲的不是很明白,或者没有完全理解的,可以通过查看B站上的视频在做进一步的理解消化。视频源

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值