一、初始对象
使用对象组织数据
-
在程序中设计表格,我们称之为:设计类(class)
class Student name = None # 记录学生姓名
-
在程序中打印生产表格,我们称之为:创建对象
# 基于类创建对象 stu_1 = Student() stu_2 = Student()
-
在程序中填写表格,我们称之为:对象属性赋值
stu_1.name = "张三" # 为学生1对象赋予名称属性值 stu_2.name = "李四" # 为学生1对象赋予名称属性值
二、成员方法
1.类的定义和使用
class 类名称: # class是关键字,表示要定义类了
类的属性 # 类的属性,即定义在类中的变量(成员变量)
类的行为 # 类的行为,即定义在类中的函数(成员方法)
创建类对象的语法:对象 = 类名称()
2.成员变量和成员方法
class Student:
name = None
age = None
def say_hi(self):
print(f"Hi大家好,我是{self.name}")
stu = Student()
stu.say_hi() # 输出:Hi大家好,我是None
定义在类内部的函数叫方法
3.成员方法的定义语法
-
在类中定义成员方法和定义函数基本一致,有细微之分:
def 方法名(self, 形参1, ..., 形参n): 方法体
self关键字是成员方法定义的时候,必须填的
- 他用来表示类对象自身的意思
- 当我们使用类对象调用方法的时候,self会自动被python传入
- 在方法内部,想要访问类的成员变量,必须使用self
4.注意事项
- self关键字,尽管在参数列表中,但是传参的时候可以忽略它
class Student:
name = None
def say_hi(self):
print(f"Hi大家好,我是{self.name}")
def say_hi2(self, msg):
print(f"很高兴认识大家,{msg}")
stu = Student()
stu.say_hi()
stu.say_hi2("很高兴认识大家")
三、类和对象
1.类和对象
-
基于类创建对象的语法:对象名 = 类名称()
class Clock: id = None price = None def ring(self): import winsound winsound.Beep(2000, 3000) clock1 = Clock() clock1.id = "003" clock1.price = 19.9 print(f"闹钟ID:{clock1.id},价格:{clock1.price}") clock1.ring() clock2 = Clock() clock2.id = "004" clock2.price = 29.9 print(f"闹钟ID:{clock2.id},价格:{clock2.price}") clock2.ring()
四、构造方法
1. 属性(成员变量)的赋值
-
class Student: name = None age = None tel = None student1 = Student() student1.name = "张三" student1.age = 20 student1.tel = "15547896547" student2 = Student() student2.name = "admin" student2.age = 29 student2.tel = "15337896547"
2. 构造方法
python类可以使用:_ _ init _ _()方法,称之为构造方法
可以实现:
- 在创建类对象(构造类)的时候,会自动执行
- 在创建类对象(构造类)的时候,将传入参数自动传递给_ _init _ _()方法使用
class Student:
# name = None
# age = None
# tel = None
def __init__(self, name, age, tel):
self.name = name
self.age = age
self.tel = tel
student1 = Student("张三", 18, "15547852536")
3.构造方法注意事项
-
init前后都有两个下划线_ _init _ _
-
构造方法也是成员方法,参数列表中也有:self
-
在构造方法内定义成员变量,需要使用self关键字
变量是定义在构造方法内部,如果要成为成员变量,需要用self来表示
def __init__(self, name, age, tel): self.name = name self.age = age self.tel = tel
五、其他内置方法
魔术方法:内置的类方法,各有各自特殊的功能,这些内置方法称为魔术方法
1._ _ str _ _字符串方法
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"Student类对象,name:{self.name}, age:{self.age}"
stu = Student("admin", 30)
print(stu) # 输出:Student类对象,name:admin, age:30
print(str(stu)) # 输出:Student类对象,name:admin, age:30
2._ _ lt _ _小于符号比较方法
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __lt__(self, other):
return self.age < other.age
stu1 = Student("admin", 30)
stu2 = Student("root", 20)
print(stu1 < stu2) # 输出:False
print(stu1 > stu2) # 输出:True
3._ _ le _ _小于等于比较符号方法
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __le__(self, other):
return self.age <= other.age
stu1 = Student("admin", 30)
stu2 = Student("root", 20)
print(stu1 <= stu2) # 输出:False
print(stu1 >= stu2) # 输出:True
4._ _ eq _ _ ,比较运算符实现方法
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __eq__(self, other):
return self.age == other.age
stu1 = Student("admin", 30)
stu2 = Student("root", 30)
print(stu1 == stu2) # 输出:True
六、封装
1. 面向对象的三大特性
基于模板(类)去创建实体(对象),使用对象完成功能开发
- 封装
- 继承
- 多态
2. 封装
封装就是将现实世界事物的属性和方法,封装到类中,描述为成员变量和成员方法,从而完成程序对现实事物的描述
私有成员
-
私有成员变量
变量名以_ _开头(两个下划线)
-
私有成员方法
方法名_ _开头(两个下划线)
使用私有成员
class 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.call_by_5g()
七、继承
1. 继承
# 单继承
class 类名(父类名):
类内容体
# 多继承
class 类名(父类1, 父类2, ..., 父类n):
类内容体
-
单继承
class Phone: IMEI = None producer = None def call_by_4g(self): print("4g通话") class Phone2022(Phone): face_id = True def call_by_5g(self): print("2022最新5g通话") phone = Phone2022() print(phone.IMEI) phone.call_by_4g() phone.call_by_5g()
-
多继承
class Phone: IMEI = None producer = None def call_by_4g(self): print("4g通话") 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()
注意事项:
多个父类中,如果有同名的成员,那么默认以继承顺序(从左到右)为优先级
即:先继承的保留,后继承的被覆盖
-
pass关键字
pass是占位语句,用来保证函数(方法)或类定义的完整性,表示无内容,空的意思
2. 复写
子类继承父类的成员属性和成员方法后,如果对其“不满意”,那么可以进行复写,即:在子类中重新定义同名的属性或方法即可。
class Phone:
IMEI = None # 序列号
producer = "INT" # 厂商
def call_by_5g(self):
print("父类的5g通话")
class MyPhone(Phone):
producer = "MI" # 复写父类的成员属性
# 复写父类的成员方法
def call_by_5g(self):
print("开启5g模式")
phone = MyPhone()
print(phone.producer)
3. 调用父类同名成员
一旦复写父类成员,那么类对象调用成员的时候,就会调用复写后的新成员。如果需要使用被复写的父类方法,需要特殊的调用方法:
-
方式一:调用父类成员
使用成员变量:父类名.成员变量
使用成员方法:父类名.成员方法(self)
-
方式二:使用super()调用父类成员
使用成员变量:super().成员变量
使用成员方法:super().成员方法(self)
八、类型注解
1. 类型注解
主要功能:
- 帮助第三方IDE工具(如pycharm)对代码进行类型推断,协助做代码提示
- 帮助开发者自身对变量进行注释
支持:
- 变量的类型注解
- 函数(方法)形参列表和返回值类型注解
类型注解的语法:
-
为变量设置类型注解(基础语法: 变量: 类型)
# 基础数据类型注解 var_1: int = 10 var_2: float = 3.1415926 var_3: bool = True var_4: str = "admin" # 类对象类型注解 class Student: pass stu: Student = Student()
-
容器类型注解
# 基础容器类型注解 my_list: list = [1, 2, 3] my_tuple: tuple = (1, 2, 3) my_set: set = {1, 2, 3} my_dict: dict = {"admin": 123456} my_str: str = "admin" # 容器类型详细注解 my_list: List[int] = [1, 2, 3] my_tuple: Tuple[int, str, bool] = (1, "admin", True) # 需要将每一个元素都标记出来 my_set: Set[int] = {1, 2, 3} my_dict: Dict[str, int] = {"admin": 123456} # 第一个是key,第二个是value
-
除了使用变量:类型,语法注解外,也可以在注释中进行类型注解
语法: # type:类型
-
注意:
一般,无法直接看出变量类型时会添加变量的类型注解
2. 函数(方法)的类型注解
-
形参注解
def 函数方法名(形参名:类型, 形参名:类型,......): pass # 例如: def add(x: int, y: int): return x + y add(1, 2)
-
返回值注解
def 函数方法名(形参名:类型, 形参名:类型,......) -> 返回值类型: pass # 例如: def func(data: list) -> list: return data
3. Union类型注解
-
使用Union[类型, …, 类型],可以定义联合类型注解
from typing import Union, Dict my_dict: Dict[str, Union[str, int]] = {"name": "admin", "age": 20}
-
Union联合类型注解,在变量注解、函数(方法)形参和返回值注解中,均可使用。
from typing import Union, Dict, List my_list: List[Union[int, str]] = [1, 2, "admin", "admin"] my_dict: Dict[str, Union[str, int]] = {"name": "admin", "age": 20} def func(data: Union[int, str]) -> Union[int, str]: pass
九、多态
1.多态
多态是指:多种状态,即完成某个行为时,使用不同的对象会得到不同的状态
同样的行为(函数),传入不同的对象,得到不同的状态
class Animal:
def speak(self):
pass
class Dog(Animal):
def speak(self):
print("汪汪汪")
class Cat(Animal):
def speak(self):
print("喵喵喵")
def make_noise(animal: Animal):
animal.speak()
dog = Dog()
cat = Cat()
make_noise(dog)
make_noise(cat)
2. 抽象类(接口)
含义是:
- 父类用来确定有哪些方法
- 具体方法实现,由子类自行决定
抽象类:含有抽象方法的类称之为抽象类(抽象类就好比定义一个标准,包含了一些抽象的方法,要求子类必须实现)
抽象方法:方法体是空实现(pass)称之为抽象方法
class AC:
def cool_wind(self):
"""制冷"""
pass
def hot_wind(self):
"""制热"""
pass
def swing_wind(self):
"""左右摆风"""
pass
class Mide_AC(AC):
def cool_wind(self):
print("美的空调核心制冷科技")
def hot_wind(self):
print("美的空调电热丝加热")
def swing_wind(self):
print("美的空调无风感左右摆风")
class GREE_AC(AC):
def cool_wind(self):
print("格力空调变频省电制冷")
def hot_wind(self):
print("格力空调电热丝加热")
def swing_wind(self):
print("格力空调静音左右摆风")
def make_cool(ac: AC):
ac.cool_wind()
midea_ac = Mide_AC()
gree_ac = GREE_AC()
make_cool(gree_ac) # 格力空调变频省电制冷
make_cool(midea_ac) # 美的空调核心制冷科技
十、综合案例
-
main.py
""" 1. 设计一个类,可以完成数据的封装 2. 设计一个抽象类,定义文件读取的相关功能,并使用子类实现具体功能 3. 读取文件,生产数据对象 4. 进行数据需求的逻辑计算(计算每一天的销售额) 5. 通过pyecharts进行图形绘制 """ from typing import List from file_define import FileReader, TextFileReader, JsonFileReader from data_define import Record from pyecharts.charts import Bar from pyecharts.options import * from pyecharts.globals import ThemeType text_file_reader = TextFileReader("2011年1月销售数据.txt") json_file_reader = JsonFileReader("2011年2月销售数据JSON.txt") jan_data: List[Record] = text_file_reader.read_data() feb_data: List[Record] = json_file_reader.read_data() # 将两个月份的数据合并为一个list来存储 all_data: List[Record] = jan_data + feb_data # 开始进行计算数据 data_dict = {} for record in all_data: if record.date in data_dict.keys(): # 当前日期有记录,可累计money 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("每日销售额.html")
-
file_define.py
""" 和文件相关的类定义 """ import json from typing import List from data_define import Record # 先定义一个抽象类来做顶层设计,确定有哪些功能实现 class FileReader: def read_data(self) -> List[Record]: # 读取文件数据,读到的每一行数据都转换为Record对象,将他们都封装到list内返回 pass class TextFileReader(FileReader): def __init__(self, path): self.path = path # 复写(实现抽象方法)父类方法 def read_data(self) -> List[Record]: f = open(self.path, "r", encoding="UTF-8") record_list: List[Record] = [] for line in f.readlines(): line = line.strip() # 消除读取到的每一行数据中的\n data_list = line.split(",") record = Record(data_list[0], data_list[1], int(data_list[2]), data_list[3]) record_list.append(record) f.close() return record_list class JsonFileReader(FileReader): def __init__(self, path): self.path = path # 复写父类方法 def read_data(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_list if __name__ == '__main__': text_file_reader = TextFileReader("2011年1月销售数据.txt") json_file_reader = JsonFileReader("2011年2月销售数据JSON.txt") list1 = text_file_reader.read_data() list2 = json_file_reader.read_data() for l in list1: print(l) for l in list2: print(l)
-
data_define.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}"