类属性/方法、静态方法

一、对象的内存空间分配

二、类属性和类方法

三、静态方法

四、综合练习

 

 

 

一、对象的内存空间分配

首先来复习一下,OOP开发中,创建对象的完整过程。

1. 在进行OOP开发时,第一件事是设计类。我们在__init__方法中定义对象的属性。使用def fun(self)来定义对象的方法,第一个参数是self,因为要在方法的内部使用到当前对象的属性或者调用当前对象的其他方法。

 

2. 当创建完类后,我们使用 类名()来创建对象。Python解释器会帮我们做两件事情:

(1) 在内存中为对象分配空间。

(2) 调用__init__方法给对象定义相应的属性。

 

但是要注意:同一个类的不同的对象,属性保存在各自的内存中。而不同的对象的方法在内存中只有一份,并不是有多少个对象,就有几份方法。在调用方法的时候,因为方法的第一个参数是self,也就是对象的引用。所以在方法内部就可以访问到调用这个方法的对象的属性或者其他的方法了。

 

我们经常把创建出来的对象叫做实例。把创建对象的动作叫做实例化。

 

 

 

 

二、类属性和类方法

在Python中,一切皆为对象。类也是一个对象。

tom = Dog()      tom属于实例对象。

class  Dog:       Dog属于类对象。

 

在程序运行时,类会被加载到内存。对象的方法(实例方法)就保存在类的内存中。

类对象在程序中只有一份。模板只需要有一个就行了。

既然类也是对象,按照之前学的,对象可以有自己的属性和方法。那么内对象是否也可以有属性和方法呢?可以。我们给类定义的属性就叫做类属性,给类定义的方法就叫做类方法

 

 

 

 

2.1 类属性

类属性, 就是给一个类定义的属性。通常使用类属性来记录这个类的一些特性。【例1】

 

 

例1:定义一个工具类。需求,要求知道这个类一共定义了多少工具对象。

 

分析:我们可以使用类属性num 来记录这个类共创建了多少个实例。每当创建一个实例时,就num++。

 

代码:

 

结果:

 

 

【科普:Python中的属性获取机制】

在编写代码的时候,通过变量.属性的方式来访问属性。Python是怎么找到这个属性的呢?

在Python中,属性获取存在一个向上查找的机制。

 

看上面的例子,工具类中定义了一个类属性Tool.count,一个实例属性name。我们在例子中通过类名.的方式来访问类属性。但是在Python中,还可以通过对象名.的方式来访问类属性。这是怎么做到的呢?

 

这个就是与Python中获取类属性的机制有关。在执行时,Python解释器会首先在对象内部查找是否有count属性,如果在对象内部没有这个属性,那么Python解释器就会向上查找类中有没有这个属性。这就是向上查找的机制。【例2】

 

例2:

 

不建议通过对象来访问类属性。容易引起困惑。而且容易导致错误。【例3】

 

 

例3:

 

结果:

 

第15行,查看了一下类属性num 为2,是对的。

第16行,把类属性num改成了5。

第17行,查看了一下类属性num果然变成了5。

但是第19行,又查看了一下类属性num,还是2,并不是5。

 

这就很奇怪了!!!

 

原因就在与,第16行,并不是修改了类属性。而是,对象名.属性 = 值的方式 是在给对象增加属性(见前面),不是在修改类属性。

 

因此,不要用对象来访问类属性。读没有问题,改有问题。最好用都不要用。

 

 

 

2.2 类方法

类方法细节:1. 修饰符@classmethod   2.第一个参数为cls。 cls就是调用这个类方法的类对象的引用。

 

 

 

例:

 

结果:

 

 

 

 

三、静态方法

在开发的时候,需要在类中对方法进行封装。

1. 如果某一个方法需要访问 对象的实例属性 或 实例方法,我们可以把这个方法定义为实例方法。

   def fun(self):

            ....

2. 如果某一个方法需要访问 类属性 或 类方法,我们可以把这个方法定义为 类方法:

    @classmethod

    def fun(cls):

           ...

但是,在开发中,还有一种情况。如果某一种方法既不需要访问实例属性、实例 方法, 又不需要访问类属性、类方法, 这个时候我们就可以考虑把它封装成一个静态方法。

 

 

 

静态方法就可以不用传第一个参数self或cls了。因为在里面也不调用别人。

 

通过类名.的方式调用静态方法。调用静态方法,不用创建对象。【例1】

 

例1:

 

结果:

 

 

四、综合练习:实例属性/方法 、类属性/方法 、静态方法

 

 

代码:

 

结果:

 

 

小结: