面向对象
提醒:本文依据b站黑马python课整顿
链接指引 => 2022新版黑马程序员python教程
一、初识对象
应用对象组织数据
在程序中是能够做到和生存中那样,设计表格、生产表格、填写表格的组织模式的。
在程序中
设计表格
,咱们称之为:设计类(class)
class Student: name = None
在程序中
打印生产表格
,咱们称之为:创建对象
# 基于类创建对象stu1 = Student()stu2 = Student()
在程序中
填写表格
,咱们称之为:对象属性赋值
stu1.name = '111'stu2.name = '111'
二、成员办法
2.1 类的定义和应用
类的应用语法:
- class是关键字,示意要定义类了
- 类的属性,即定义在类中的变量(成员变量)
- 类的行为,即定义在类中的函数(成员办法)
class 类名称: 类的属性 类的行为
创立类对象的语法:
对象 = 类名称()
2.2 成员变量和成员办法
类中定义的属性(变量),咱们称之为:成员变量
类中定义的行为(函数),咱们称之为:成员办法
2.2.1 成员办法的定义语法
def 办法名(self, 行参1, ..., 行参n): 办法体
能够看到,在办法定义的参数列表中,有一个:self
关键字
self关键字是成员办法定义的时候,必须填写
的。
- 它用来示意类对象本身的意思
- 当咱们应用类对象调用办法的是,self会主动被python传入
在办法外部,想要拜访类的成员变量,必须应用self
def say_hi(self): print(f"hi大家好,我是{self.name}")
注意事项:self关键字,只管在参数列表中,然而传参的时候能够疏忽它。
三、类和对象
基于类创建对象的语法: 对象名 = 类名称()
四、构造方法
Python类能够应用:__init__()
办法,称之为构造方法。
能够实现:
- 在创立类对象(结构类)的时候,
会主动执行。
- 在创立类对象(结构类)的时候,
将传入参数主动传递给__init__办法应用。
在构造方法内定义成员变量,须要应用self
关键字
class Student: def __init__(self, name, age, address): self.name = name self.age = age self.address = addressstu = Student('天天', 30, '1111')
案例:
学生信息录入
# 学生信息录入class Student: id = None name = None age = None address = None def insert (self, id, name, age, address): self.id = id self.name = name self.age = age self.address = address print(f'学生{id}信息录入实现,信息为:【学生姓名:{name},年龄:{age},地址:{address}】')idx = 10for i in range(0, idx): print(f'以后录入第{i+1}位学生信息,总共需录入10位学生信息') name = input('请输出学生姓名:') age = input('请输出学生年龄:') address = input('请输出学生地址:') stu = Student() stu.insert(i+1, name, age, address) if i+1 == 10: print('10位学生信息录入结束!')
五、其它内置办法(魔术办法)
上文学习的__init__ 构造方法,是Python类内置的办法之一。
这些内置的类办法,各自有各自非凡的性能,这些内置办法咱们称之为:魔术办法
办法 | 性能 |
---|---|
__init__ | 构造方法,可用于创立类对象的时候设置初始化行为 |
__str__ | 用于实现类对象转字符串的行为 |
__lt__ | 用于2个类对象进行小于或大于比拟 |
__le__ | 用于2个类对象进行小于等于或大于等于比拟 |
__eq__ | 用于2个类对象进行相等比拟 |
5.1 __str__
字符串办法
内存地址没有多大作用,咱们能够通过__str__
办法,管制类转换为字符串的行为。
- 办法名:
__str__
- 返回值:字符串
- 内容:自行定义
class Record: def __init__(self, date,order_id,money,province): self.date = date # 订单日期 self.order_id = order_id # 订单ID self.money = money # 订单金额 self.province = province # 销售省份 def __str__(self): return f"{self.date}, {self.order_id}, {self.money}, {self.province}"
5.2 __lt__
小于符号比拟办法(__gt__
大于符号比拟办法)
间接对2个对象进行比拟是不能够的,然而在类中实现__lt__
办法,即可同时实现:小于符号 和 大于符号 2种比拟比拟大于符号的魔术办法是:__gt__
不过,实现了__lt__
,__gt__
就没必要实现了
- 办法名:
__lt__
- 传入参数:other,另一个类对象
- 返回值:True 或 False
- 内容:自行定义
5.3 __le__
小于等于比拟符号办法
魔术办法:__le__
可用于:<=、>=两种比拟运算符上。
- 办法名:
__le__
- 传入参数:
other
,另一个类对象- 返回值:
True
或False
- 内容:自行定义
>=
符号实现的魔术办法是:__ge__
不过,实现了__le__
,__ge__
就没必要实现了
5.4 __eq__
,比拟运算符实现办法
不实现 __eq__
办法,对象之间能够比拟,然而是比拟内存地址,也即是:不同对象==比拟肯定是False后果
。
实现了__eq__
办法,就能够依照本人的想法来决定2个对象是否相等了。
- 办法名:
__eq__
- 传入参数:
other
,另一个类对象- 返回值:
True
或False
- 内容:自行定义
六、封装
面向对象的三大个性
- 封装
- 继承
- 多态
封装示意的是,将事实世界事物的:
- 属性
- 行为
封装到类中,形容为:
- 成员变量
- 成员办法
6.1 公有成员
既然事实事物有不公开的属性和行为,那么作为事实事物在程序中映射的类,也应该反对。
类中提供了公有成员的模式来反对。
- 公有成员变量
- 公有成员办法
定义公有成员的形式非常简单,只须要:
- 公有成员变量:变量名以__结尾(2个下划线)
- 公有成员办法:办法名以__结尾(2个下划线)
即可实现公有成员的设置
class Phone: __is_5g_enable = False # 公有成员变量 def __check_5g(self): # 公有成员办法 print('5g开启')
练习:
设计带有公有成员的手机
# 设计带有公有成员的手机import randomclass Phone: __is_5g_enable = False def __check_5g(self): if self.__is_5g_enable: print('5g开启') else: print('5g敞开,应用4g网络') def call_by_5g(self): self.__check_5g() print('正在通话中...')phone: Phone = Phone()phone.call_by_5g()a = random.randint(1,2)
七、继承
- 什么是继承?
继承就是一个类,继承另外一个类的成员变量和成员办法 语法:
- 子类构建的类对象,能够
- 有本人的成员变量和成员办法
- 应用父类的成员变量和成员办法
- 单继承和多继承
单继承:一个类继承另一个类
多继承:一个类继承多个类,依照程序从左向右顺次继承
多继承中,如果父类有同名办法或属性,先继承的优先级高于后继承 pass关键字
的作用是什么pass
是占位语句,用来保障函数(办法)或类定义的完整性,示意无内容,空的意思
7.1 继承的根底语法
7.1.1 单继承
class 类名(父类名): 类内容体
继承分为:单继承和多继承
应用如图语法,能够实现类的单继承。
继承示意:将从父类那里继承(复制)来成员变量和成员办法(不含公有
7.1.2 多继承
一个类,能够继承多个父
class 类名(父类1,父类2,...., 父类n): 类内容体
多继承注意事项:
多个父类中,如果有同名的成员,那么默认以继承程序(从左到右)为优先级。
即:先继承的保留,后继承的被笼罩
7.2 复写和应用父类成员
7.2.1 复写
复写:子类继承父类的成员属性和成员办法后,如果对其“不称心”,那么能够进行复写。
即:在子类中从新定义同名的属性或办法即可。
class FileReader: def read_file(self): """读取文件的数据,读到的每一条数据都转换为Record对象,将他们封装到list""" pass# 文本文件的读取class TextFileRead(FileReader): def __init__(self, path): self.path = path # 定义文件门路 # 复写父类的办法 def read_file(self): print('11111')
7.2.2 调用父类同名成员
一旦复写父类成员,那么类对象调用成员的时候,就会调用复写后的新成员
如果须要应用被复写的父类的成员,须要非凡的调用形式:
形式1:
- 调用父类成员
- 应用成员变量:
父类名.成员变量
- 应用成员办法:
父类名.成员办法(self)
形式2:
- 应用
super()
调用父类成员 - 应用成员变量:
super().成员变量
- 应用成员办法:
super().成员办法()
只能在子类内调用父类的同名成员。
子类的类对象间接调用会调用子类复写的成员
八、类型注解
8.1 变量的类型注解
- 为变量设置类型注解
根底语法:变量: 类型
留神:
元组类型设置类型具体注解,须要将每一个元素都标记进去
字典类型设置类型具体注解,须要2个类型,第一个是key第二个是value
- 除了应用 变量: 类型, 这种语法做注解外,也能够在正文中进行类型注解。
语法:# type: 类型
8.2 函数(办法)的类型注解
函数和办法的形参类型注解语法:
def 函数办法名(形参名:类型,形参名:类型,.....): pass
同时,函数(办法)的返回值也是能够增加类型注解的。
语法如下:
def 函数办法名(形参名:类型,形参名:类型,.....) -> 返回值类型: pass
def read_file(x: int, y: int) -> list[int]: pass
8.3 Union类型
Union的应用形式:
- 导包:from typing import Union
- 应用:Union[类型, ......, 类型]
九、多态
多态,指的是:多种状态,即实现某个行为时,应用不同的对象会失去不同的状态。
9.1 抽象类(接口)
这种设计的含意是:
- 父类用来确定有哪些办法
- 具体的办法实现,由子类自行决定
抽象类:含有形象办法的类称之为抽象类
形象办法:办法体是空实现的(pass)称之为形象办法
抽象类的作用
- 多用于做顶层设计(设计标准),以便子类做具体实现。
- 也是对子类的一种软性束缚,要求子类必须复写(实现)父类的一些办法
- 并配合多态应用,取得不同的工作状态。
十、案例
数据分析案例
main.py
""" 面向对象,数据案例剖析"""from pyecharts.charts import Line, Barfrom pyecharts.options import *from pyecharts.globals import ThemeTypefrom file_define import TextFileRead, JsonFileReader, FileReaderfrom data_define import Recordtext_file_reader = TextFileRead('./data/2011年1月销售数据.txt')json_file_reader = JsonFileReader('./data/2011年2月销售数据JSON.txt')jan_data: list[Record] = text_file_reader.read_file()feb_data: list[Record] = json_file_reader.read_file()# 将两个月份的数据合并为一个listall_data: list[Record] = jan_data + feb_data# 数据计算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)# 可视化图表开发bar = Bar(init_opts=InitOpts(theme=ThemeType.LIGHT))bar.add_xaxis(list(data_dict.keys()))bar.add_yaxis('销售额', list(data_dict.values()), label_opts=LabelOpts(is_show=False))bar.set_global_opts( title_opts=TitleOpts(title='每日销售额'))bar.render('每日销售额echarts.html')
file_defined.py
""" 和文件相干的类定义"""import jsonfrom data_define import Recordclass FileReader: def read_file(self) -> list[Record]: """读取文件的数据,读到的每一条数据都转换为Record对象,将他们封装到list""" pass# 文本文件的读取class TextFileRead(FileReader): def __init__(self, path): self.path = path # 定义文件门路 # 复写父类的办法 def read_file(self) -> list[Record]: f = open(self.path, 'r', encoding="UTF-8") record_list: list[Record] = [] for line in f.readlines(): line = line.strip() # 打消空格和换行 data_list = line.split(',') record = Record(data_list[0], data_list[1], int(data_list[2]), data_list[3]) record_list.append(record) # print(record_list) f.close() return record_list# Json文件的读取class JsonFileReader(FileReader): def __init__(self, path): self.path = path # 定义文件门路 def read_file(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) record = Record(data_dict['date'], data_dict['order_id'], int(data_dict['money']), data_dict['province']) record_list.append(record) f.close() return record_listif __name__ == "__main__" : text_file = TextFileRead('./data/2011年1月销售数据.txt') text_json = JsonFileReader('./data/2011年2月销售数据JSON.txt') list1 = text_file.read_file() list2 = text_json.read_file() for l in list1: print(l) for l in list2: print(l)
data_defined.py
""" 数据定义的类"""class Record: def __init__(self, date,order_id,money,province): self.date = date # 订单日期 self.order_id = order_id # 订单ID self.money = money # 订单金额 self.province = province # 销售省份 def __str__(self): return f"{self.date}, {self.order_id}, {self.money}, {self.province}"
总结
以上就是python向对象,之后会继续更新,欢送大家点赞关注呀~~