01 术语——实例
1、使用面向对象开发,第一步是 设计类。
2、使用 类名() 创建对象,创建对象的动作有两步:
- 在内存中为对象 分配空间
- 调用初始化方法为对象初始化。
3、对象创建后,内存中就有了一个对象的实实在在的存在——实例。
注意:同一个类的对象拥有的方法在内存中只有一份,在调用这个方法时,我们会把这个对象传递给方法的第一个参数self,这样就可以访问到调用这个方法的对象的自己的属性或者调用其他的对象的方法了。
结论:
- 每一个对象都有自己独立的内存空间,保存各自不同的属性
- 多个对象的方法在内存中只有一份,在调用方法时,需要把对象的引用通过self传递到方法内部
4、通常也会把:
- 创建出来的 对象 叫做类的实例
- 创建对象这一动作叫做 实例化
- 对象的属性叫做实例属性
- 对象调用的方法叫做实例方法
02 类是一个特殊的对象
- python中一切皆是对象
class A:定义的类 属于类对象
obj1 = A() 属于实例对象 - 在程序运行时,类同样会被加载到内存,类对象在程序中只有一份,使用一个类可以创建出很多对象实例。
- 除了封装实例的属性和方法外,类对象还可以拥有自己的属性和方法:
类属性
类方法
通过 类名. 的方式可以访问类的属性和调用类的方法。
03 类属性和实例属性
- 概念:类属性就是给类对象中定义的属性,通常用来记录与这个类相关的特征。类属性不会用来记录 具体对象的特征。
- 示例需求:
定义一个工具类
每件工具都有自己的name
需求——知道使用这个类,创建了多少个工具对象?
代码:
class Tool: # 使用赋值语句定义类属性,记录创建工具对象的属性 count = 0 def __init__(self,name): self.name = name # 每创建一个对象,计数+1 Tool.count += 1 tool1 = Tool("剪刀") tool2 = Tool("锤子") print(Tool.count)
04 属性的获取机制(科普)
在python中 属性的获取 存在一个 向上查找机制
因此要访问类属性有两种方式:
- 类名.类属性
- 对象.类属性(不推荐)
注意:如果使用 对象.属性 = 值 赋值语句,只会给对象添加一个属性,而不会影响类属性的值
05 类方法
- 类方法是针对类对象定义的方法
- 在类方法内部可以直接访问类属性或者调用此类对象的其他类方法
- 语法:
@classmethod def 类方法名(cls): pass
类方法需要用修饰器 @classmethod 来标识,告诉解释器这是一个类方法
类方法的第一个参数是 cls
由哪一个类调用的方法,方法内部的cls就是哪一个类的引用
这个参数和实例方法的第一个参数 self 类似(使用其他名称也可以,不过习惯使用cls)
通过 类名. 调用类方法时,不需要传递cls参数
示例需求 :
- 定义一个工具类
- 每件工具都有自己的name
- 需求——在 类 封装一个 show_tool_count 的类方法,输出使用当前这个类创建的对象个数。
class Tool: # 使用赋值语句定义类属性,记录创建工具对象的属性 count = 0 @classmethod def show_tool_count(cls): # 在类方法内部可以直接使用 cls. 访问类属性或者类方法 print("工具对象的数量%d" % cls.count) def __init__(self,name): self.name = name # 每创建一个对象,计数+1 Tool.count += 1 tool1 = Tool("剪刀") tool2 = Tool("锤子") # 在外界使用 类名.方法名 调用类方法 Tool.show_tool_count()
06 静态方法
在开发时,如果需要在类中封装一个方法,这个方法:
- 既不需要访问实例属性 或者调用实例方法
- 也不需要访问类属性 或者调用类方法
这个时候可以把这个方法封装成一个静态方法。
语法如下:
@staticmethod def 静态方法名(): pass
静态方法需要修饰器 @staticmethod 来标识,告诉解释器这是一个静态方法
通过 类名. 调用静态方法,不需要创建对象就可以调用静态方法
class Dog(object): @staticmethod def run(): # 不访问实例属性/类属性 print("小狗跑了") # 通过 类名. 调用静态方法,不需要创建对象 Dog.run()