python 类中的 self 与 cls
python
本文字数:1.5k 字 | 阅读时长 ≈ 5 min

python 类中的 self 与 cls

python
本文字数:1.5k 字 | 阅读时长 ≈ 5 min

python 中的类是一种抽象的数据类型,是对一类具有相同属性和方法的对象的抽象,它定义了该集合中每个对象所共有的属性和方法,对象是类的实例

python 中类就是一个抽象的集合,包含属性和方法。对象是类的实例,也就是类的具体实现。一般来说,在使用类中某个方法时,需要先实例化,在了解这两个概念之后,我们讲一下类中的 selfcls

1. self 与 cls

在类中,selfcls 都是指向类的实例的指针,但是 self 指向的是类的实例,而 cls 指向的是类本身。selfcls 都可以用于访问类中的属性和方法

selfcls 一般和@staticmethod、@classmethod 一起使用,下面看一个基本的例子:

class A(object):
    def foo1(self):
        print("hello, ", self)

    @staticmethod
    def foo2():
        print("hello")

    @classmethod
    def foo3(cls):
        print("hello, ", cls)

a = A()  # 初始化类实例
a.foo1()  # hello,  <__main__.A object at 0x7f396b06a6e0>
print(a)  # <__main__.A object at 0x7f396b06a6e0>

a.foo2()  # hello

a.foo3()  # hello,  <class '__main__.A'>
print(A)  # <class '__main__.A'>

在上面例子中,我们定义了一个类 A 并初始化了一个类实例 a。在类中,定义了三个函数 foo1foo2foo3,其中 foo2 用装饰器@staticmethod 装饰,代表这个函数是一个静态方法,foo3 用装饰器@classmethod 装饰,代表这个函数是一个类方法

从输出中可以看出,类实例 a 调用了 foo1 函数,输出 hello 与 self,这里的 self 代表的就是实例化的 a,可以看到 self 与 print(a)的结果是相同的。而 foo2foo3 函数中,没有使用 self,而是使用了 cls,这里的 cls 代表的是类本身,可以看到 cls 与 print(A)的结果是相同的

2. @statistic 与@classmethod

有了上面基本的认识之后,我们更详细的讨论@staticmethod 和@classmethod,self 指向的是类的实例,而 cls 指向的是类本身,selfcls 都可以访问类中的属性和方法

我们在看下面这个例子

class Student(object):
    name = "harry"  # 类属性
    def __init__(self, name):
        self.name = name  # 实例属性

    def say1(self):  # 实例方法
        print("hello, ", self)

    @staticmethod
    def say2():  # 静态方法
        print("hello")

    @classmethod
    def say3(cls):  # 类方法
        print("hello, ", cls)

s = Student('Bob')  # 实例化类
print(s.name)  # Bob
print(Student.name)  # harry

s.say1()  # hello,  <__main__.Student object at 0x7f9d7f7efa30>
Student.say1()  # wrong
Student.say1(s) # true

s.say2()  # hello
Student.say2()  # hello

s.say3()  # hello,  <class '__main__.Student'>
Student.say3()  # hello,  <class '__main__.Student'>

我们构建了一个类 Student,分别定义了类属性、实例属性、实例方法、静态方法、类方法。顾名思义,类属性类方法指的是类中固有属性和方法,实例属性和实例方法指的是类实例化之后的属性和方法。在上述例子中,我们从类 Student 中实例化了一个类实例 s

3. 为什么要有静态方法和类方法

我们从一个例子来看类内各种方法的区别

class A(object):
    def foo1(self):
        print("hello, ", self)

    @staticmethod
    def foo2():
        print("hello")

    @classmethod
    def foo3(cls):
        print("hello, ", cls)

a = A()  # 初始化类实例
print(a.foo1)  # <bound method A.foo1 of <__main__.A object at 0x7f50126b26e0>>
print(a.foo2)  # <function A.foo2 at 0x7f5012505d80>
print(a.foo3)  # <bound method A.foo3 of <class '__main__.A'>>

从输出结果来看一目了然

为什么在类内要设置各种方法?

9月 09, 2024
9月 06, 2024