Python中的cls变量的功能和用法

 更新时间:2025年06月04日 08:54:14   作者:DECHIN  
本文介绍了在Python的classmethod装饰的类方法的cls变量的意义,通过几个不同的示例对比,凸显cls变量在Python编程中的应用场景,本文通过一些具体示例,来演示cls参数的功能和用法,感兴趣的朋友一起看看吧

技术背景

在Python的类型设计中,有时候会遇到一个cls参数。其实cls参数就是一个约定俗成的名称,用其他的名字也能正常运行但不建议这么用。它的作用类似于实例方法中的self参数,代表的是类本身,可以用于访问类的参数和类的方法。本文通过一些具体示例,来演示cls参数的功能和用法。

简单类实现

首先我们用普通的方法做一个最基本的测试案例:

class Test:
    def __init__(self):
        self.prefix = "Hello\t"
    def excute(self, x):
        print (self.prefix+x)
t = Test()
x = "Bob"
t.excute(x)
x = "Alice"
t.excute(x)

这里Test类型的操作逻辑是,在初始化函数中初始化一个prefix变量,然后在excute中调用打印函数,打印prefix变量和一个外部输入变量的整合字符串,执行效果如下:

Hello   Bob
Hello   Alice

这个方法的一个局限性在于,类Test中的函数,如excute函数,必须要新建一个实例t之后,才能够调用到它的excute方法。如果跳过初始化的步骤直接调用excute方法:

class Test:
    def __init__(self):
        self.prefix = "Hello\t"
    def excute(self, x):
        print (self.prefix+x)
Test.excute()

运行结果会告诉你,这需要两个变量的输入才能够正常的运行:

Traceback (most recent call last):
  File "/home/test_cls.py", line 8, in <module>
    Test.excute()
TypeError: Test.excute() missing 2 required positional arguments: 'self' and 'x'

例如,我们先初始化一个t实例,但是方法调用我们不调用t中的excute函数,而是直接调用Test类中的函数:

class Test:
    def __init__(self):
        self.prefix = "Hello\t"
    def excute(self, x):
        print (self.prefix+x)
t = Test()
x = "Bob"
Test.excute(t, x)

这样也是可以正常运行的:

Hello   Bob

classmethod方法

通过classmethod方法,可以允许我们不需要在外部对类初始化,而直接访问到类的内部属性、参数和函数。也就是对于classmethod装饰的函数,约定使用cls变量作为开头。

class Test:
    prefix = "Hello\t"
    @classmethod
    def excute(cls, x):
        print (cls.prefix+x)
x = "Bob"
Test.excute(x)

这样就可以直接在外部调用到类的内部函数:

Hello   Bob

当然,前面提到过,这里即使换一个变量名,也是可以正常运行的:

class Test:
    prefix = "Hello\t"
    @classmethod
    def excute(self, x):
        print (self.prefix+x)
x = "Bob"
Test.excute(x)

因为第一个参数代表的是类本身,因此可以执行成功:

Hello   Bob

这里需要说明的是,classmethod装饰器的作用,就是把函数的第一个参数相关的内容给省去了,如果不使用classmethod进行装饰,例如:

class Test:
    prefix = "Hello\t"
    def excute(cls, x):
        print (cls.prefix+x)
x = "Bob"
Test.excute(x)

这样运行会报错:

Traceback (most recent call last):
  File "/home/test_cls.py", line 7, in <module>
    Test.excute(x)
TypeError: Test.excute() missing 1 required positional argument: 'x'

提示的内容是参数缺失,其实也就是少了一个初始化的步骤。那么有一种情况是,类似于prefix这种的类属性是在__init__函数中定义的,这是比较常见的情况。在这种情况下,如果不初始化一个实例,就无法访问到初始化参数。但是前面也提到了,cls就代表类本身,那么自然可以通过cls来访问类中的函数,包括初始化的函数:

class Test:
    def __init__(self):
        self.prefix = "Hello\t"
    @classmethod
    def excute(cls, x):
        cls.__init__(cls)
        print (cls.prefix+x)
x = "Bob"
Test.excute(x)

这个代码可以被正确执行:

Hello   Bob

同时,通过classmethod,可以修改类的属性:

class Test:
    prefix = "Hello\t"
    @classmethod
    def excute(cls, x):
        print (cls.prefix+x)
        cls.prefix = cls.prefix+x+"\t"
x = "Bob"
Test.excute(x)
x = "Alice"
Test.excute(x)

这里在excute函数中,每次打印之后,都会修改一下prefix参数,所以打印输出结果如下:

Hello   Bob
Hello   Bob     Alice

当然,修改属性这样的操作,在普通的类实现中也是可以操作的:

class Test:
    def __init__(self):
        self.prefix = "Hello\t"
    def excute(self, x):
        print (self.prefix+x)
        self.prefix = self.prefix+x+"\t"
t = Test()
x = "Bob"
t.excute(x)
x = "Alice"
t.excute(x)

用self得到的结果是一样的:

Hello   Bob
Hello   Bob     Alice

如果不使用classmethod,也可以通过staticmethod来实现一个类似功能:

class Test:
    def __init__(self):
        self.prefix = "Hello\t"
    @staticmethod
    def excute(self, x):
        print (self.prefix+x)
        self.prefix = self.prefix+x+"\t"
t = Test()
x = "Bob"
Test.excute(t, x)
x = "Alice"
Test.excute(t, x)

但是staticmethod不对参数进行初始化,虽然可以在外部直接调用类函数,但是需要手动初始化一个实例。输出结果是一致的:

Hello   Bob
Hello   Bob     Alice

总结概要

本文介绍了在Python的classmethod装饰的类方法的cls变量的意义,通过几个不同的示例对比,凸显cls变量在Python编程中的应用场景。对于大多数的场景来说,使用普通的Python类和函数定义即可。如果需要在类的外部使用类的内部函数,但是可能有多个不同初始化的类输入,那么可以使用staticmethod进行装饰。如果只有一个类,而有多种不同的输入场景下,可以使用classmethod进行装饰。

版权声明

本文首发链接为:https://www.cnblogs.com/dechinphy/p/cls.html

作者ID:DechinPhy

更多原著文章:https://www.cnblogs.com/dechinphy/

请博主喝咖啡:https://www.cnblogs.com/dechinphy/gallery/image/379634.html

到此这篇关于Python中的cls变量的文章就介绍到这了,更多相关Python中的cls变量内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python延时操作实现方法示例

    Python延时操作实现方法示例

    这篇文章主要介绍了Python延时操作实现方法,结合实例形式分析了Python基于sched库与time库实现延时操作的方法,需要的朋友可以参考下
    2018-08-08
  • Python列表生成式与生成器操作示例

    Python列表生成式与生成器操作示例

    这篇文章主要介绍了Python列表生成式与生成器操作,结合实例形式分析了Python列表生成式与生成器的功能、使用方法及相关操作技巧,需要的朋友可以参考下
    2018-08-08
  • python图像处理之镜像实现方法

    python图像处理之镜像实现方法

    这篇文章主要介绍了python图像处理之镜像实现方法,实例分析了镜像的实现原理与具体操作方法,需要的朋友可以参考下
    2015-05-05
  • Python打造出适合自己的定制化Eclipse IDE

    Python打造出适合自己的定制化Eclipse IDE

    这篇文章主要介绍了Python打造出适合自己的定制化Eclipse IDE的相关资料,需要的朋友可以参考下
    2016-03-03
  • Python列表数据如何按区间分组统计各组个数

    Python列表数据如何按区间分组统计各组个数

    这篇文章主要介绍了Python列表数据如何按区间分组统计各组个数,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • Python的互斥锁与信号量详解

    Python的互斥锁与信号量详解

    这篇文章主要介绍了Python的互斥锁与信号量详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • Pandas:DataFrame对象的基础操作方法

    Pandas:DataFrame对象的基础操作方法

    今天小编就为大家分享一篇Pandas:DataFrame对象的基础操作方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-06-06
  • python中enumerate的用法实例解析

    python中enumerate的用法实例解析

    这篇文章主要介绍了python中enumerate的用法,对Python初学者而言是非常重要的概念,需要的朋友可以参考下
    2014-08-08
  • Pytorch可视化之Visdom使用实例

    Pytorch可视化之Visdom使用实例

    Visdom 是一个专门用于 PyTorch 的交互式可视化工具,可以对实时数据进行丰富的可视化,帮助我们实时监控在远程服务器上进行的科学实验,这篇文章主要给大家介绍了关于Pytorch可视化之Visdom使用的相关资料,需要的朋友可以参考下
    2021-08-08
  • Python3 中作为一等对象的函数解析

    Python3 中作为一等对象的函数解析

    这篇文章主要介绍了Python3 中作为一等对象的函数,本文通过实例代码讲解的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-12-12

最新评论