python中的类是一种抽象的数据类型,是对一类具有相同属性和方法的对象的抽象,它定义了该集合中每个对象所共有的属性和方法,对象是类的实例
python中类就是一个抽象的集合,包含属性和方法。对象是类的实例,也就是类的具体实现。一般来说,在使用类中某个方法时,需要先实例化,在了解这两个概念之后,我们讲一下类中的self
与cls
1. self与cls
在类中,self
和cls
都是指向类的实例的指针,但是self
指向的是类的实例,而cls
指向的是类本身。self
和cls
都可以用于访问类中的属性和方法
self
和cls
一般和@staticmethod、@classmethod一起使用,下面看一个基本的例子:
1 | class A(object): |
在上面例子中,我们定义了一个类A
并初始化了一个类实例a
。在类中,定义了三个函数foo1
,foo2
和foo3
,其中foo2
用装饰器@staticmethod装饰,代表这个函数是一个静态方法,foo3
用装饰器@classmethod装饰,代表这个函数是一个类方法
从输出中可以看出,类实例a调用了foo1
函数,输出hello与self,这里的self代表的就是实例化的a,可以看到self与print(a)的结果是相同的。而foo2
和foo3
函数中,没有使用self,而是使用了cls,这里的cls代表的是类本身,可以看到cls与print(A)的结果是相同的
2. @statistic与@classmethod
有了上面基本的认识之后,我们更详细的讨论@staticmethod和@classmethod,self
指向的是类的实例,而cls
指向的是类本身,self
和cls
都可以访问类中的属性和方法
我们在看下面这个例子
1 | class Student(object): |
我们构建了一个类Student
,分别定义了类属性、实例属性、实例方法、静态方法、类方法。顾名思义,类属性类方法指的是类中固有属性和方法,实例属性和实例方法指的是类实例化之后的属性和方法。在上述例子中,我们从类Student
中实例化了一个类实例s
- 类属性和实例属性:类属性是类的固有属性,实例属性是类实例化之后的属性。在上面例子中,我们通过初始化实例
s
来覆盖掉了类属性name
- 实例方法:实例方法是类实例化之后的方法,可以通过实例化类来调用,也可以通过类来调用,但是通过类来调用时,需要传入实例化的类。在上面例子中,我们通过实例化类
s
来调用了实例方法say1
,而通过类Student
来调用实例方法say1
时,会报错,因为没有传入实例化的类,如果要不报错,需要传入实例化的类,即Student.say1(s)
- 静态方法:静态方法是类的固有方法,可以通过实例化类来调用,也可以通过类来调用。在上面例子中,我们通过实例化类
s
来调用了静态方法say2
,而通过类Student
来调用静态方法say2
时,也可以正常调用 - 类方法:类方法是类的固有方法,可以通过实例化类来调用,也可以通过类来调用。在上面例子中,我们通过实例化类
s
来调用了类方法say3
,而通过类Student
来调用类方法say3
时,也可以正常调用
3. 为什么要有静态方法和类方法
我们从一个例子来看类内各种方法的区别
1 | class A(object): |
从输出结果来看一目了然
foo1
是实例方法,他是面向对象的实例化对象的一个实例方法,即实例a
的一个实例方法foo2
是静态方法,他是一个<function>,即他与类或者类实例都本质的关系,可以认为是在类外定义的一个函数,那为什么不在类外定义呢?我的理解是与语法糖有关,python是面向对象的编程,将函数写在类内起到了规范的作用foo3
是类方法,他是类A
自带的方法,不需要实例化即可使用
为什么在类内要设置各种方法?
- 为什么要用实例方法:需要改变实例属性的时候用到实例方法
- 为什么要用类方法:需要改变类属性的时候用到类方法
- 为什么要用静态方法:既不需要改变实例属性,也不需要改变类属性的时候用到静态方法