一,设计类实例(Class)
#创建类
class Student:
name=None
gender=None
nationality=None#国籍
native_place=None#籍贯
age=None
#创建对象
student1=Student()
student1.name='张飞'
student1.gender='男'
student1.nationality='中国'
student1.native_placed="安徽"
student1.age=23
print(student1.name)
print(student1.gender)
print(student1.nationality)
print(student1.native_placed)
print(student1.age)
二,类的成员方法
1. 类的定义语法:
class 类名:
类属性(成员变量)
类行为(成员方法,定义在类中函数)
class Student:
name=None
gender=None
nationality=None#国籍
native_place=None#籍贯
age=None
2. 成员方法
def 方法名(self,形参1,形参2.......):
方法体
self关键字是成员变量定义时必须填写的,他用来表示类对象自身的意思,在方法体内部如果想要访问类的成员变量,必须使用self。
class Student:
name=None
gender=None
nationality=None#国籍
native_place=None#籍贯
age=None
def fun1(self):
print(f"大家好,我是{self.name}")
虽然self在定义类方法的时候必须存在,但是在类对象引用类方法传参时,self相当于透明的,可以不用理会。
student1=Student()
student1.name='张飞'
student1.fun1()#不用给self传参
传参数:
class Student:
name=None
# gender=None
# nationality=None#国籍
# native_place=None#籍贯
# age=None
def fun1(self,msg):
print(f"大家好,我是{self.name},{msg}")
#创建对象
student1=Student()
student1.name='张飞'
student1.fun1("很牛逼")
3. 类和对象:
对象名=类名()
对象名.类成员变量/方法
#设计闹钟类
class Clock:
id=None
price=None
def ring(self):
import winsound
winsound.Beep(2000,3000)#设计一个响铃,频率两秒一次,一次3秒
#构建对象
clock1=Clock()
clock1.price=13
clock1.id="1234"
print(f"闹钟id{clock1.id},价格:{clock1.price}")
clock1.ring()
4.构造方法
- init()方法,称之为构造方法。
- 创建类对象时候,自动执行。
- 创建类对象时将参数传递给_init_()方法使用。
- 可以缩减每次创建对象后都要一一调用类变量赋值:
引入构造方法后,在创建对象时直接给参数,将类内部变量赋值。
"""
演示类的构造方法
"""
# 演示使用构造方法对成员变量进行赋值
# 构造方法的名称:__init__
class Student:
def __init__(self, name, age ,tel):
self.name = name
self.age = age
self.tel = tel
print("Student类创建了一个类对象")
stu = Student("周杰轮", 31, "18500006666")
print(stu.name)
print(stu.age)
print(stu.tel)
5.其他内置方法
- 上节中的_init_方法,是python中类内置的方法之一,以下还有其他类方法,我们称之为魔术方法。注意:这下方法的前后都有两个下划线
5.1_ str _()字符串方法
(1)作用:__str__方法用于返回对象的描述信息,用来控制类对象输出形式,如果不使用__str__方法,直接print,或者return,返回的是对象的内存地址。如果在__str__中定义了描述信息,print或者return时,返回的就不是内存地址,显示更友好,实现了类到字符串的转化。
输出类对象:
class Student:
def __init__(self, name, age):
self.name = name # 学生姓名
self.age = age # 学生年龄
stu1 = Student("周杰轮", 31)
stu2 = Student("林俊节", 36)
print(stu1)
print(stu2)
使用字符串方法 _ str _:
# __str__魔术方法
def __str__(self):
return f"Student类对象,name:{self.name}, age:{self.age}"
5.2 _ lt _()方法
,小于,大于比较方法
直接拿两个对象进行比较是不行的,直接报错,要在类中使用 _ lt _()方法定义好比较哪个类变量。如果对则输出True,否则是FALSE
def __lt__(self, other):
return self.age < other.age#定义好比较哪个类变量
print(stu1<stu2)
print(stu1>stu2)
5.3 le()方法:
用来实现对象小于等于,大于等于的比较
# # __le__魔术方法
def __le__(self, other):
return self.age <= other.age
stu1 = Student("周杰轮", 31)
stu2 = Student("林俊节", 36)
print(stu1<=stu2)
print(stu1>=stu2)
5.4__eq__()方法
- 用于两个对象进行是否相等的比较,返回值是True或者false
def __eq__(self, other):
return self.age == other.age
stu1 = Student("周杰轮", 31)
stu2 = Student("林俊节", 36)
print(stu1==stu2)
三,封装,继承,多态
1.面向对象的三大特性
- 面向对象编程的思想:基于模板(类)去创建实体(对象),使用对象完成功能开发。
- 面向对象包含三大主要特征:封装,继承,多态
2.封装
2.1封装的定义
- 封装是将现实世界中的事务的属性,行为封装到类中,描述为**成员变量,成员方法。**从而实现程序对现实世界事物的描述。
- 现实中的事物,有属性和行为,但不代表这些这些属性和行为都是开放给用户使用的。
2.2类的私有成员
- 私有成员:对于现实事物中不公开的属性,在程序中描述时应定义为私有的,即私有成员变量,私有成员方法。
- 定义方法:在变量或方法前加_ _两个下划线开头。
- 对于私有成员,无法被类对象直接调用。
- 对于私有成员,对象调用时都没有任何提示。
- 对于私有成员,类对象无法直接使用,并不代表其毫无意义,私有成员的定义是为了在类的内部使用的。
class Phone:
# 定义的私有成员,当前手机电压
__current_voltage=None
def __init__(self,current_voltage):
self.__current_voltage=current_voltage
#私有成员方法
def __keep_single_core(self):
print("电压不足,使手机Cpu以单核运行")
#定义共有成员
def using_5g(self):
if self.__current_voltage>=1:#调用私有成员变量
print("运行5g")
else:
self.__keep_single_core()#调用私有成员方法
phone=Phone(0)
phone.using_5g()
3.继承
3.1 单继承基础语法
- 子类继承父类,子类继承父类的成员变量或方法(不含私有成员)
- 语法:
- 单继承案例:
class Phone:
TMEI=None#序列号
producer="huawei"#厂商
def call_by_4g(self):
print("4g通话")
#继承
class Phone2023(Phone):
face_id="1001"
def call_by_5g(self):
print("2023年新技术")
phone=Phone2023()
print(phone.producer)#调用父类中的成员变量输出
phone.call_by_5g()
phone.call_by_4g()#调用父类中的成员方法输出
3.2多继承基础语法
- 多继承中,父类中存在同名属性或方法,先继承的优先级高。
"""
演示面向对象:继承的基础语法
"""
# 演示单继承
class Phone:
IMEI = None # 序列号
producer = "ITCAST" # 厂商
def call_by_4g(self):
print("4g通话")
class Phone2022(Phone):
face_id = "10001" # 面部识别ID
def call_by_5g(self):
print("2022年新功能:5g通话")
phone = Phone2022()
print(phone.producer)
phone.call_by_4g()
phone.call_by_5g()
# 演示多继承
class NFCReader:
nfc_type = "第五代"
producer = "HM"
def read_card(self):
print("NFC读卡")
def write_card(self):
print("NFC写卡")
class RemoteControl:
rc_type = "红外遥控"
def control(self):
print("红外遥控开启了")
class MyPhone(Phone, NFCReader, RemoteControl):
pass #空,占位作用,用来保证函数或者类的结构完整性
phone = MyPhone()
phone.call_by_4g()
phone.read_card()
phone.write_card()
phone.control()
print(phone.producer)
- 运行结果:
3.3复写和使用父类成员
- 子类继承父类的成员变量和方法后,如果对其不满意可以重新进行复写。在子类中重新定义同名的属性或方法。
class Phone:
IMEI=None#序列号
producer="huawei"
def call_by_5G(self):
print("使用5g通话")
#子类
class myphone(Phone):
producer = "xiaomi"
def call_by_5G(self):
print("省电模式")
# print("使用5g通话"),下一行代码作用与此句相同
Phone.call_by_5G(self)
super().call_by_5G()
phone=myphone()
print(f"生产商{phone.producer}")
phone.call_by_5G()
4.类型注解
4.1 变量的类型注解
- 语法:
变量:类型
var_1: int = 10
var_2: str = "itheima"
var_3: bool = True
#类对象类型注解
class Student:
pass
stu: Student = Student()#stu对象的类型是Student
# 基础容器类型注解
# my_list: list = [1, 2, 3]
# my_tuple: tuple = (1, 2, 3)
# my_dict: dict = {"itheima": 666}
# 容器类型详细注解
"""#list类型 而且内部元素是int型"""
my_list: list[int] = [1, 2, 3]
my_tuple: tuple[int, str, bool] = (1, "itheima", True)
"""对于字典元素的注解一个是key,一个是value"""
my_dict: dict[str, int] = {"itheima": 666}
- 在注释中进行注解,语法:
#type:类型
import random
import json
# 在注释中进行类型注解
var_1 = random.randint(1, 10) # type: int
var_2 = json.loads('{"name": "zhangsan"}') # type: dict[str, str]
def func():
return 10
var_3 = func() # type: int
- 什么时候使用:
4.2 方法注解
- 对参数类型进行注解:
- 对返回值进行注解
4.3Union类型
- 联合类型
- 语法:Union[类型,类型]
- 对函数联合注解
5.多态
5.1多态的定义
class Animal:
def speak(self):
pass
#继承与复写
class Dog(Animal):
def speak(self):
print("汪汪")
class Cat(Animal):
def speak(self):
print("喵喵")
#定义方法
def make_noice(animal:Animal):#注解
animal.speak()
dog=Dog()
cat=Cat()
make_noice(dog)
make_noice(cat)
5.2 抽象类(接口)
- 在父类中定义的方法体中用pass空实现,父类只进行拥有哪些方法的确定,不需要实现,继承他的子类具体实现。
- 抽象类配合多态实现各厂家自行设计,但要遵守应有的功能。
# 演示抽象类
class AC:
def cool_wind(self):
"""制冷"""
pass
def hot_wind(self):
"""制热"""
pass
def swing_l_r(self):
"""左右摆风"""
pass
class Midea_AC(AC):
def cool_wind(self):
print("美的空调制冷")
def hot_wind(self):
print("美的空调制热")
def swing_l_r(self):
print("美的空调左右摆风")
class GREE_AC(AC):
def cool_wind(self):
print("格力空调制冷")
def hot_wind(self):
print("格力空调制热")
def swing_l_r(self):
print("格力空调左右摆风")
def make_cool(ac: AC):#注解提示传参时AC类型
ac.cool_wind()
midea_ac = Midea_AC()
gree_ac = GREE_AC()
make_cool(midea_ac)
make_cool(gree_ac)
6.综合案例-数据处理
6.1 数据的读取
- 计算每日的销售额(以面向对象的思想)
- 封装数据对象,设计数据封装类data_define
文件:data_define.py
"""数据定义的类"""
class Record:#用来记录数据的基本信息
def __init__(self,date,order_id,money,province):
self.date = date # 日期
self.order_id = order_id # 订单号
self.money = money # 销售额
self. province = province # 省份
def __str__(self):#防止文件类中返回值类型是Record对象地址
return f"{self.date},{self.order_id},{self.money},{self.province}"
4. 读取数据,设计FileReader类
文件:file_define.py
strip()方法用于消除读到的内容首尾含有的 \t,\n
#和文件相关的类
#定义一个抽象类,确定需要哪些功能
import json
from data_define import Record
class FileReader:#抽象类
"""读取文件数据并将读取的数据转换成Record对象 ,将他们封装在list内返回即可"""
def file_reader(self)->list[Record]:
pass
#处理文本数据
class TextFileReader(FileReader):
def __init__(self,path):#定义变量记录文件路径
self.path=path
#复写父类方法
def file_reader(self) ->list[Record]:
f=open(self.path,"r",encoding="utf-8")
record_list:list[Record]=[]
for line in f.readlines():
line=line.strip()#读到的line中自带换行符,要去掉
datalist=line.split(",")#以逗号分割
print(datalist)
record=Record(datalist[0],datalist[1],int(datalist[2]),datalist[3])
record_list.append(record)
f.close()
return record_list
#Json文件处理
class JsonFileReader(TextFileReader):
def __init__(self, path): # 定义变量记录文件路径
self.path = path
# 复写父类方法
def file_reader(self) -> list[Record]:
f = open(self.path, "r", encoding="utf-8")
record_list: list[Record] = []
for line in f.readlines():
data_dict=json.loads(line)#将JSON数据装换为字典
record=Record(data_dict["date"],data_dict["order_id"],int(data_dict["money"]),data_dict["province"])
record_list.append(record)
f.close()
return record_list
if __name__ == '__main__':
# text=TextFileReader("F:\Python学习资料\第13章资料/2011年1月销售数据.txt")
json_file=JsonFileReader("F:\Python学习资料\第13章资料/2011年2月销售数据JSON.txt")
# list1= text.file_reader()
list2=json_file.file_reader()
for l in list2:
print(l)
6.2 数据的计算
- 计算数据对象,对对象进行逻辑运算
#计算每日的销售额(以面向对象的思想)
#2封装数据对象,设计数据封装类data_define
#4pycharts绘图
from file_define import TextFileReader,JsonFileReader
from data_define import Record
#1读取数据,设计FileReader类
#创建两个类对象
text_file=TextFileReader("F:\Python学习资料\第13章资料/2011年1月销售数据.txt")
json_file=JsonFileReader("F:\Python学习资料\第13章资料/2011年2月销售数据JSON.txt")
#读取一二月数据
Jan_data:list[Record]=text_file.file_reader()
Feb_data:list[Record]=json_file.file_reader()
#此时两个月份数据格式一样,可以合并为一个list存放
all_data:list[Record]=Jan_data+Feb_data
#3计算数据对象,对对象进行逻辑运算,求解每一天的数据额度
#定义空字典存贮计算的数据{"2011-01-01":1534,"2011-01-02":630......}
data_dict={}
for record in all_data:
if record.date in data_dict.keys():
#如果读到的日期字典中存在的,当前日期已经存在,只需要和之前的记录累加
data_dict[record.date]+=record.money
else:
#是第一条记录,我们要补上第一条记录
data_dict[record.date]=record.money
#测试
#print(data_dict)
6.3 绘图
#4pycharts绘图
bar=Bar()
bar.add_xaxis(list(data_dict.keys()))#x轴显示日期
bar.add_yaxis("销售额",list(data_dict.values()))
bar.set_global_opts(
title_opts=TitleOpts(title="每日销售额")
)
bar.render("每日销售额柱状图.html")
优化:
(1)数字太多,使它不显示
bar.add_yaxis("销售额",list(data_dict.values()),label_opts=LabelOpts(is_show=False))
(2)改变柱状图颜色,蓝色
bar=Bar(init_opts=InitOpts(theme=ThemeType.LIGHT))
结果: