面向对象:
- 好处:
- 1、使代码之间的角色关系更明确
- 2、增强了代码的可扩展性
- 3、规范了对象的属性和技能
- 短处:
- 结局的不确定性
类:
具有相同属性和技能的一类事物.
对象:
类的具体表现.
class 关键字
class 类名: (类名应该首字母大写)
代码块.
country = 'China' 第一部分:静态变量,静态字段
def __init__(self,name,age): 第二部分:动态方法,函数,方法
pass
def func(self):
pass
类从结构上考虑就是分这两大部分:静态属性 + 动态属性
- 创建类:
- 关键字class + 类名:属性
方法(函数)
- 类名:
- 1、类名查看类中所有的变量(字段),方法(函数):类名.__dict__
- 2、类名对静态变量进行操作
- 方法一、类名.__dict__["变量名"] 只能查,报错不能增删改 **不用**
- 方法二、类名.变量名 可增删改查 *****常用******
- 3、类名对动态方法(函数)进行操作
- 类名.__dict__["方法名"] 或 类名.方法名 都只能查,不能增删改
- 类调用函数必须给self赋值,哪怕赋的值是无用的,不然根据函数位置参数定义,就会因缺少参数报错
- 创建对象(即类的实例化)
- 语法:obj = 类名()
- 一旦写下了类型+括号,就在内存中做了下面3件事:
- 初始版:
- 1、在内存中为先创建的对象创建了一个空的对象空间(但有类的指针)
- 2、对象一旦创建,python内部自动在对象所属的类中执行了__init__()方法,并将空的对象空间传给self,将相应的值传给init方法相应的形参
- 3、执行init方法时,根据传过来的实参为对象封装属性,最后将封装完善好的对象返回给 类名() (可以为对象指定一个变量接收)
- 完整版:
- 1、className() 自动执行本类中的__new__方法,类中没有去object类中执行__new__(cls,*args,**kwargs),创建一个对象空间,返回给className()
(如果有new方法,就不去object类,且如果new方法不创建对象空间,那么就没有对象空间,没法封装属性)
- 2、自动执行__init__方法,将对象空间传给self,init 方法为这个对象空间封装一些属性,最后将封装好的属性返回给className()
- 单例模式(永远只能创建一个实例)
- 思路就是:设置一个开关,不要让对象自己去object类中找__new__方法
- ------------answer---------------
- classs Single_instance(object):
- __instance = None
- def __new__(cls,*args,**kwargs):
- if Single_instance.__instance is None:
- cls.__instance = object.__new__(cls,*args,**kwargs)
- return cls.__instance (不管None否都返回)
- 对象:
- 1、对象查看对象中所有的属性:对象名.__dict__ (因为对象没有建立自己的方法,故此时只能返回属性的字典)
- 2、对象对对象本身的属性的操作
- 方法1、对象名.属性 可以增删改查
- 方法2、对象名.__dict__[属性名] 可以增删改查 ******不用*****
- 3、对象对类中静态字段的操作
- 3.1、对类静态变量(字段)的操作:只能查,不能增删改
- 3.2、对类方法的操作:只能引用,不能增删改
- self 是位置参数,默认接收的是对象的对象空间,约定俗成叫self
- 在类的非__init__方法中,也可以给对象添加一些属性,但如要使用这些属性,前提必须先执行这个方法
- 类一旦创建了,就会执行里面的代码块,如果里面有print语句,就会执行,不像函数要调用才执行
- 类 只能操作自己的属性及方法,无法操作对象的属性和方法,因为每个对象的属性都是自己独有的
- --------------------------------------------------------------------------------
- 类属性的补充
- 一、查看类的属性和方法
- dir(类名) ----->返回名字列表
- 类名.__dict__ ----->返回一个字典
- 二、特殊的类属性
- 类名.__name__ # 类的名字
- 类名.__doc__ # 类的文档字符串
- 类名.__base__ # 类的第一个父类名(继承中从左到右)
- 类名.__bases__ # 类的所有父类 -----> 返回一个元组
- 类名.__dict__ # 类的所有属性与方法
- 类名.__module__ # 类定义所在的模块 【在类所在的脚本中执行和 print(__name__) 一样都是固定的名字:__main__】
- 类名.__class__ # 实例对应的类(仅新式类中)
- 类的命名空间、对象(实例)的命名空间
- 创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性
- 静态属性就是直接在类中定义的变量(静态变量或者叫静态字段)
- 动态属性就是定义在类中的方法
- 类的静态属性是共享给所有对象的
- 类的动态属性是绑定到所有对象的
- 创建一个对象/实例就会创建一个对象/实例的名称空间(开始里面只有对应类对象的指针,以便找到类的__init__()方法来传空间地址及封装对象属性),存放对象/实例的名字,称为对象/实例的属性
- 对象的查询顺序:先从对象空间去找,对象的空间没有此变量或者方法,通过对象中的类对象指针去类中寻找.
- 类的查询顺序: 直接从类本身找.它无法查找对象的属性,因为是不同的命名空间
- 无论创建多少个对象,都是独立开辟的命名空间,各个空间互相不能查找,干扰
- 案例:如何计算一个类被实例化了多少个对象?
- 组合:给一个类的对象,封装一个属性,这个属性是另一个类的对象
- 组合2:想获取将另一个类的对象,并不一定要传进来,也可以在类中直接创建另一个类的对象再赋值给本类的属性
二、__init__与__new__方法的区别
1. 执行时间:__new__ 先执行
2. 返回值:__new__有返回值,为对象,__init__没有返回值
3. 方法不一样:__new__是静态方法,__init__是类方法