1、类
1、认识类
1、定义类: class 类名(遵循驼峰命名),类可以从字面意思上了解,就是一类事物的统称,植物、水果、大海、大山等,都是一类事物,例如:class Car:定义一个车类;class Fruit:定义一个水果类
2、类的特性:
1、类中会定义这个类共有的特点和状态,可以理解为这类事物的属性和方法
2、类可以调用自己的属性,但是 不可调用它对象的属性
写一个简单的类了解一下:
# 定义一个车类
class Car:
# 定义类的2个属性
wheel = "车轮子"
isNewEnergy = True
2、类中的init方法
1、概述:
1、init方法在类定义的时候,就会给对象定义实例属性
2、初始化对象过程:函数的名字是固定的不能变
2、实例化对象的过程,会调用init方法
4、实例属性都会在init函数里去定义,基本上不会在外面去定义
5、init方法没有返回值,不能写 return,写了默认是None
6、类的方法可以调用了init函数中的属性,需要加 self,例如:self.属性名
如下举例:
# 定义类
class Car:
# 定义类的属性
wheel = "四个轮子"
engine = True
# 定义init方法,并且在init中定义了2个对象的属性,cl和lg
def __init__(self, cl, lo):
self.color = cl
self.logo = lo
print(f"正在生成一辆车···")
print(f"车的颜色是{self.color}的,车的品牌是{self.logo}")
# 初始化的时候,会调用init函数,一定要写init函数里面的形参,并且个数要对上
my_car = Car("黑色","奥迪");
print(my_car.logo)
# 类不能调用实例属性,在init方法中的基本上都是实例属性
print(Car.logo) # AttributeError: type object 'Car' has no attribute 'logo'
# 类可以调用自己的属性
Car.wheel # 输出 四个轮子
2、init方法将属性写为常量
init方法中的参数设置值,设置后就是一个默认值,但是在初始化对象时可以修改属性值
class Car:
wheel = "四个轮子"
engine = True
# 定义init方法,并给对象的属性赋值
def __init__(self,cl = "黑色",lg = "五菱神车"):
self.color = cl
self.logo = lg
print(f"我正在开着一辆{self.color}的{self.logo}在兜风~")
# 实例化一个对象,会使用默认的属性值
her_car = Car() # 输出:我正在开着一辆黑色的五菱神车在兜风~
# 在初始化时,可以修改init方法中的属性值
he_car = Car("白色","特斯拉") # 输出:我正在开着一辆白色的特斯拉在兜风~
3、self 关键字解读
1、概述
1、self指的就是对象本身,类里面的方法默认会自己加上self,用来表示一个对象
2、self 变量可以改名字,但是不建议修改
3、在类里面定义实例属性,一定要加self,表示这是一个实例对象的属性,不加会报错
4、类中的方法
类中的方法等价于在类里面写函数,类中的函数,类和类的对象都可以调用,举例如下:
2、对象
定义对象:建立在类的基础上,先有类再有对象,可以使用 对象名 = 类名() 来定义一个对象,对象可以调用类中的方法和属性,也可以修改类中init函数的参数值
3、属性
概述:
1、类/对象的特征和状态,例如:车类,它有颜色、logo、车轮、油车还是电车
2、可以通过类获取,也可以通过对象获取
3、可以修改、增加类的属性值
4、在对象(实例)中,属性是个体有的,非这个类都有的,例如:水果中,香蕉的皮是黄色的,火龙果的皮是玫红色的,这就是他们的个体特性
5、对象修改属性,修改的都是对象个体的属性,非整个类或者所有这个类的对象的属性
备注:一般对象属性使用较类的属性多,因此后续大部分情况都会定义为实例的属性
1、动态属性(反射)
1、概述
动态属性就是给类和对象设置属性、获取属性、删除属性、修改属性的操作,主要是用在项目中,一些测试数据不能提前在设计测试用例的时候,必须是测试运行起来中间产生的数据,例如:
- token:登录成功后反悔了token,用户鉴权令牌
- 项目创建后,产生的id
以上这2种,需要动态添加,不能使用init函数初始化、提前设置
2、动态属性的关键字
- hasattr(对象/类,"属性名"): 判断类/对象是否有属性 ,结果是布尔值 ——True False
- getattr(对象/类,"属性名"): 获取类/对象的属性的值
- delattr(对象/类,"属性名"): 删除类/对象的属性
使用举例:
class Car:
wheel = "True"
engine = "True"
def __init__(self,cl = "白色",lg = "宝马"):
= "四个轮子的车车"
self.color = cl
self.logo = lg
print("正在生成一俩车")
def driving(self):
print("正在行驶哦~")
# 使用动态属性添加元素
setattr(Car,"speed","350km/h")
print(Car.speed)
# 删除一个元素
deleteAttr = delattr(Car,"wheel")
print(deleteAttr)
# print(Car.wheel) # 报错,已经没有这个元素了
Traceback (most recent call last):
File "E:\python310\py001\类和对象2\pratices\动态属性.py", line 19, in <module>
print(Car.wheel) # 报错
AttributeError: type object 'Car' has no attribute 'wheel'
# 判断当前类是否有该元素
speed = hasattr(Car,"speed")
print(speed)
4、扩展
1、已知参数类型,进行传参
在写函数的时候,如果参数确定类型,那么可以使用一下方式,这样在函数中也可以调用这个类型的对象的方法和属性,如下举例:
# 先定义一个类
class Fruit:
apple = "青苹果"
banana = "绿香蕉"
def __init__(self):
self.ftuits = []
def add_fruit(self,name):
if name in self.ftuits:
print("此种水果已经在水果种类里~")
else:
self.ftuits.append(name)
print("添加成功~")
# 定义一个函数
def get_fruit(obj: Fruit):
obj.apple
obj.banana
obj.add_fruit("猕猴桃")
fruit = Fruit()
get_fruit(fruit) # 输出 添加成功
2、init函数中设置常量
# 写一个车类
class Car:
wheel = "True"
engine = "True"
def __init__(self,name,cl = "白色",lg = "宝马"):
= "四个轮子的车车"
self.color = cl
self.logo = lg
print("正在生成一俩车")
print(f"{}车的颜色是{self.color},品牌是{self.logo}")
# 实例化一个车对象,传递3个参数
new_car1 = NewEnergyCar("五个轮子的","黑色","五菱神车")
输出:
正在生成一俩车
四个轮子的车车车的颜色是黑色,品牌是五菱神车
# 实例化一个车对象,传递2个参数
new_car2 = NewEnergyCar("粉色的","五菱")
输出:
正在生成一俩车
四个轮子的车车车的颜色是五菱,品牌是宝马
######结论:直接在init函数中赋值的,就是对象的常量,在初始化时,是否传参不会报错,对结果无影响######
3、给类添加属性有2种方式
- 直接添加
- 使用动态方法添加
看如下例子:
# 方式一
Car.speed = "350km/h"
# 方式二
setattr(Car,"speed","350km/h")
5、继承
1、一重继承
1、继承的概述
类比生活中的例子,类似于“皇位继承”,而在代码中集成的好处是,可以不要从0开始写代码,可以继承父类的方法和属性直接继承过来。
2、继承的特点
1、类的继承是语法:直接在括号里写另外一个类的名字,例如:class NewCar(Car),就是NewCar类继承了Car类,可以继承父类的所有方法和属性
2、子类可以写自己的方法,父类不能使用子类的方法
3、子类还可以重写父类的方法:子类方法跟父类同名的方法,会使用子类的方法(相当于子类重写了父类的方法,init函数也不例外)
4、子类可以多继承和多层继承:同时继承多个父类,拥有多个父类的属性和方法
简单举例:
class Car:
wheel = "True"
engine = "True"
def __init__(self,cl = "白色",lg = "宝马"):
self.color = cl
self.logo = lg
print("正在生成一俩车")
print(f"车的颜色是{self.color},品牌是{self.logo}")
def driving(self):
print("正在开车···")
# 调用实例的属性
print(f"我开车的颜色是{self.color},品牌是{self.logo}")
# 调用方法
self.recharge()
def recharge(self):
print(f"我的小车车正在充电~")
# 写一个新的类,继承 Car
class NewEnergyCar(Car):
# 如果在子类里写init方法,相当于重写了父类的init方法,子类的对象就不能调用父类的方法和属性了
def __init__(self,isnew):
self.isnew = isnew
print(f"这是一辆{isnew}车")
def save_money(self):
print("新能源车可以省钱~")
new_car = NewEnergyCar("黑色")
new_car.recharge()
print(new_car.wheel)
# 输出:
这是一辆黑色车
我的小车车正在充电~
True
# 如果按照父类的init的方法去实例化一个对象,则会报错
new_car1 = NewEnergyCar("黑色","五菱神车")
# 输出报错,这是因为子类重写了父类的init方法,就不能再用父类的init参数,去实例化对象了
Traceback (most recent call last):
File "E:\python310\py001\类和对象2\pratices\d2_类的继承.py", line 36, in <module>
new_car1 = NewEnergyCar("黑色","五菱神车")
TypeError: __init__() takes 2 positional arguments but 3 were given
注释掉子类的init方法后,可以继续使用父类的init函数参数初始化对象,如下举例:
new_car1 = NewEnergyCar("黑色","五菱神车")
# 输出
正在生成一俩车
车的颜色是黑色,品牌是五菱神车
2、多重继承
多重继承,即一个类有多个父类,这个类的对象,可以调用所有负累的属性和方法,举列如下:
class Car:
wheel = "True"
engine = "True"
def __init__(self,cl = "白色",lg = "宝马"):
= "四个轮子的车车"
self.color = cl
self.logo = lg
print("正在生成一俩车")
print(f"{}车的颜色是{self.color},品牌是{self.logo}")
def driving(self):
print("正在开车···")
# 调用实例的属性
print(f"我开车的颜色是{self.color},品牌是{self.logo}")
# 调用方法
self.recharge()
def recharge(self):
print(f"我的小车车正在充电~")
# 写一个新的类,继承 Car
class NewEnergyCar(Car):
def save_money(self):
print("新能源车可以省钱~")
class Robotcar():
def AITools(self):
print("语音识别功能~")
# 继承2个类
class AutoCar(NewEnergyCar,Robotcar):
def info(self):
print("我继承了2个类")
# 这个对象可以调用所有继承类的方法
auto_car = AutoCar()
auto_car.AITools()
auto_car.info()
# 输出
正在生成一俩车
四个轮子的车车车的颜色是白色,品牌是宝马
语音识别功能~
我继承了2个类
备注,需要注意如下情况,Car类中的init函数有常量,那么在子实例化时,需要加上这个变量,不然会报错:
class Car:
wheel = "True"
engine = "True"
def __init__(self,name,cl = "白色",lg = "宝马"):
# 此时name就是一个常量
= "四个轮子的车车"
self.color = cl
self.logo = lg
print("正在生成一俩车")
# 则 AutoCar的对象需要这样写
autoCar = AutoCar("随便写")
# 不写会报错
autoCar = AutoCar()
错误信息:
Traceback (most recent call last):
File "E:\python310\py001\类和对象2\pratices\d2_类的继承.py", line 35, in <module>
auto_car = AutoCar()
TypeError: __init__() missing 1 required positional argument: 'name'