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

作者:

文章目录
  • 在Python的类型设计中,有时候会遇到一个cls参数。其实cls参数就是一个约定俗成的名称,用其他的名字也能正常运行但不建议这么用。它的作用类似于实例方法中的self参数,代表的是类本身,可以用于访问类的参数和类的方法。本文通过一些具体示例,来演示cls参数的功能和用法。
  • 首先我们用普通的方法做一个最基本的测试案例: class Test: def __init__(self): self.prefix = “Hellot” 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   BobHello   Alice 这个方法的一个局限性在于,类Test中的函数,如excute函数,必须要新建一个实例t之后,才能够调用到它的excute方法。如果跳过初始化的步骤直接调用excute方法: class Test: def __init__(self): self.prefix = “Hellot” 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 = “Hellot” def excute(self, x): print (self.prefix+x) t = Test() x = “Bob” Test.excute(t, x) 这样也是可以正常运行的: Hello   Bob
  • 通过classmethod方法,可以允许我们不需要在外部对类初始化,而直接访问到类的内部属性、参数和函数。也就是对于classmethod装饰的函数,约定使用cls变量作为开头。 class Test: prefix = “Hellot” @classmethod def excute(cls, x): print (cls.prefix+x) x = “Bob” Test.excute(x) 这样就可以直接在外部调用到类的内部函数: Hello   Bob 当然,前面提到过,这里即使换一个变量名,也是可以正常运行的: class Test: prefix = “Hellot” @classmethod def excute(self, x): print (self.prefix+x) x = “Bob” Test.excute(x) 因为第一个参数代表的是类本身,因此可以执行成功: Hello   Bob 这里需要说明的是,classmethod装饰器的作用,就是把函数的第一个参数相关的内容给省去了,如果不使用classmethod进行装饰,例如: class Test: prefix = “Hellot” 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 = “Hellot” @classmethod def excute(cls, x): cls.__init__(cls) print (cls.prefix+x) x = “Bob” Test.excute(x) 这个代码可以被正确执行: Hello   Bob 同时,通过classmethod,可以修改类的属性: class Test: prefix = “Hellot” @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   BobHello   Bob     Alice 当然,修改属性这样的操作,在普通的类实现中也是可以操作的: class Test: def __init__(self): self.prefix = “Hellot” 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   BobHello   Bob     Alice 如果不使用classmethod,也可以通过staticmethod来实现一个类似功能: class Test: def __init__(self): self.prefix = “Hellot” @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   BobHello   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类名和类方法cls修改类变量的值 Python中的cls变量的功能和用法 深入浅析python 中的self和cls的区别 python self,cls,decorator的理解
  • 目录
    • 技术背景
    • 简单类实现
    • classmethod方法
    • 总结概要
    • 版权声明

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

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

    class Test:
        def __init__(self):
            self.prefix = "Hellot"
        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 = "Hellot"
        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 = "Hellot"
        def excute(self, x):
            print (self.prefix+x)
    t = Test()
    x = "Bob"
    Test.excute(t, x)

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

    Hello   Bob

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

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

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

    Hello   Bob

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

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

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

    Hello   Bob

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

    class Test:
        prefix = "Hellot"
        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 = "Hellot"
        @classmethod
        def excute(cls, x):
            cls.__init__(cls)
            print (cls.prefix+x)
    x = "Bob"
    Test.excute(x)

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

    Hello   Bob

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

    class Test:
        prefix = "Hellot"
        @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 = "Hellot"
        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 = "Hellot"
        @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类名和类方法cls修改类变量的值
    • Python中的cls变量的功能和用法
    • 深入浅析python 中的self和cls的区别
    • python self,cls,decorator的理解

    站内搜索