1 类
1.1 类的成员方法
1.1.1 类的成员
- 设计表格,称之为:设计类(class)
- 打印表格,称之为:创建对象
- 填写表格,称之为:对象属性赋值
# 1.设计类(类比生活中: 设计一张登记表)
class Student:
name = None #记录学生姓名
gender = None #记录学生性别
nationality = None #记录学生国籍
native_place = None #记学生籍贯
age = None
# 2.创建对象(类比生活中: 打印一张登记表)
stu_1 = Student()
# 3.对象属性赋值(类比生活中:填写表单)
stu_1.name = "林俊杰"
stu_1.gender = "男"
stu_1.nationality = "中国"
stu_1.native_place = "山东省"
stu_1.age = 31
# 4. 获取对象中记录的信息
print(stu_1.name)
print(stu_1.gender)
print(stu_1.nationality)
print(stu_1.native_place)
print(stu_1.age)
林俊杰
男
中国
山东省
31
1.1.2 类的方法
展示self的作用:
class Student:
name = None
def say_hi(self):
print(f"大家好呀,我是{self.name},欢迎大家多多关照")
def say_hi2(self, msg):
print(f"大家好呀,我是{self.name},{msg}")
stu = Student()
stu.name = "周杰伦"
stu.say_hi()
stu.say_hi2("哎呦不错哟")
stu2 = Student()
stu2.name = "林俊杰"
stu2.say_hi2("小伙子我看好你")
大家好呀,我是周杰伦,欢迎大家多多关照
大家好呀,我是周杰伦,哎呦不错哟
大家好呀,我是林俊杰,小伙子我看好你
1.2 类和对象
不同对象间互不干扰:
# 设计一个闹钟类
class Clock:
id = None
price = None
def ring(self):
import winsound
winsound.Beep(2000, 3000) #2000表示频率,3000表示持续时间(毫秒)
# 构建2个闹钟对象并让其工作
clock1 = Clock()
clock1.id = "003032"
clock1.price = 19.99
print(f"闹钟ID:{clock1.id},价格:{clock1.price}")
clock1.ring()
clock2 = Clock()
clock2.id = "003033"
clock2.price = 21.99
print(f"闹钟ID:{clock1.id},价格:{clock1.price}")
clock2.ring()
闹钟ID:003032,价格:19.99
闹钟ID:003032,价格:19.99
1.3 案例 学生信息录入
class Student:
def __init__(self, name, age, address):
self.name = name
self.age = age
self.address = address
stu_list = []
count = int(input())
for i in range(1, count + 1):
print(f"当前录入第{i}位学生信息,总共需录入{count}位学生信息")
stu_name = input("请输入学生姓名:")
stu_age = input("请输入学生年龄:")
stu_add = input("请输入学生地址:")
stu = Student(stu_name, stu_age, stu_add)
stu_list.append(stu)
stu_data = stu_list[i - 1]
print(f"学生{i}信息录入完成,信息为:【学生姓名:{stu_data.name},年龄:{stu_data.age},地址:{stu_data.address}】")
3
当前录入第1位学生信息,总共需录入3位学生信息
请输入学生姓名:小谭
请输入学生年龄:29
请输入学生地址:虎山街21号
学生1信息录入完成,信息为:【学生姓名:小谭,年龄:29,地址:虎山街21号】
当前录入第2位学生信息,总共需录入3位学生信息
请输入学生姓名:小李
请输入学生年龄:23
请输入学生地址:虎山街45号
学生2信息录入完成,信息为:【学生姓名:小李,年龄:23,地址:虎山街45号】
当前录入第3位学生信息,总共需录入3位学生信息
请输入学生姓名:小山
请输入学生年龄:26
请输入学生地址:唐山路45号
学生3信息录入完成,信息为:【学生姓名:小山,年龄:26,地址:唐山路45号】
1.4 类里的魔术方法
1.4.1 __init__
__init__使用方法一
# 构造方法的名称:__init__
class Student:
def __init__(self, name, age, tel):
self.name = name
self.age = age
self.tel = tel
print("Student类创建了一个类对象")
stu = Student("李明", 12, 12345)
print(f"名字是{stu.name}")
print(f"年龄是{stu.age}")
print(f"电话是{stu.tel}")
Student类创建了一个类对象
名字是李明
年龄是12
电话是12345
__init__使用方法二
# 构造方法的名称:__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
print("Student类创建了一个类对象")
stu = Student("李明", 12, 12345)
print(f"名字是{stu.name}")
print(f"年龄是{stu.age}")
print(f"电话是{stu.tel}")
Student类创建了一个类对象
名字是李明
年龄是12
电话是12345
1.4.2 __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("李明", 12)
print(stu)
print(str(stu))
Student类对象,name:李明,age:12
Student类对象,name:李明,age:12
1.4.3 __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("李明", 12)
stu2 = Student("林俊杰", 14)
print(stu1 < stu2)
True
1.4.4 __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("李明", 14)
stu2 = Student("林俊杰", 12)
print(stu1 >= stu2)
1.4.5 __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("李明", 14)
stu2 = Student("林俊杰", 14)
print(stu1 == stu2)
True
封装
总结
面向对象三大主要特性
- 封装
- 继承
- 多态
私有方法和变量
私有方法和变量的使用
私有成员无法被类对象使用,但是可以被其它的成员使用。
class Phone:
__current_voltage = 0.5 # 当前手机运行电压
def __keep_single_core(self):
print("让CPU以单核模式运行")
def call_by_5g(self):
if self.__current_voltage >= 1:
print("5G通话已开启")
else:
print("电量不足,无法使用5g通话")
self.__keep_single_core()
phone = Phone()
phone.call_by_5g()
电量不足,无法使用5g通话
让CPU以单核模式运行
案例:设计带有私有成员的手机
class Phone:
__is_5g_enable = False # 当前5g运行状态
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()
5g关闭,使用4g网络
正在通话中
继承
class Phone:
IMEI = None # 序列号
producer = "HM" # 厂商
def call_by_4g(self):
print("4g通话")
class Phone2022(Phone):
face_id = "10001" # 面部识别id
phone = Phone2022()
print(phone.face_id+phone.producer)
print(phone.IMEI)
10001HM
None
复写
子类继承父类的成员属性和成员方法后,如果对其“不满意”,那么可以进行复写
复写方法
class Phone:
IMEI = None # 序列号
producer = "ITCAST" # 厂商
def call_by_5g(self):
print("父类的5g通话")
class MyPhone(Phone):
producer = "ITHEIMA"
def call_by_5g(self):
print("子类的5g通话")
phone = MyPhone()
phone.call_by_5g()
print(phone.producer)
子类的5g通话
ITHEIMA
调用父类同名成员
一旦复写父类成员,那么类对象调用成员的时候,就会调用复写后的新成员。如果需要使用被复写的父类的成员,需要特殊的调用方式:
方式一
class Phone:
IMEI = None # 序列号
producer = "ITCAST" # 厂商
def call_by_5g(self):
print("父类的5g通话")
class MyPhone(Phone):
producer = "ITHEIMA"
def call_by_5g(self):
print(f"父类的厂商是:{Phone.producer}")
Phone.call_by_5g(self)
phone = MyPhone()
phone.call_by_5g()
父类的厂商是:ITCAST
父类的5g通话
方式二
当传递两个参数时,super(type, obj) 会返回一个基于 type 类的 obj 实例的父类的 super 对象。这样可以在子类中调用父类中的方法,并传递正确的实例参数。
class Phone:
IMEI = None # 序列号
producer = "ITCAST" # 厂商
def call_by_5g(self):
print("父类的5g通话")
class MyPhone(Phone):
producer = "ITHEIMA"
def call_by_5g(self):
print(f"父类的厂商是:{super().producer}")
super().call_by_5g()
phone = MyPhone()
phone.call_by_5g()
父类的厂商是:ITCAST
父类的5g通话
多态
多态的使用
示例一
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)
汪汪汪
喵喵喵
示例二
# 空调
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.cool_wind()
def make_hot(ac: AC):
ac.hot_wind()
gree_ac = Gree_AC()
midea_ac = Midea_AC()
make_cool(gree_ac)
make_cool(midea_ac)
make_hot(gree_ac)
make_hot(midea_ac)
格力空调制冷
美的空调制冷
格力空调制热
美的空调制热
类型注解
总述
1.什么是类型注解,有什么作用?
在代码中涉及数据交互之时,对数据类型进行显式的说明,可以帮助:
- PyCharm等开发工具对代码做类型推断协助做代码提示
- 开发者自身做类型的备注
2.类型注解支持:
- 变量的类型注解
- 函数(方法)的形参和返回值的类型注解
3.变量的类型注解语法
- 语法1: 变量: 类型
- 语法2: 在注释中,# type: 类型
4.注意事项
类型注解只是提示性的,并非决定性的。数据类型和注解类型无法对应也不会导致错误。
5.使用情形?
注解方法
变量类型注解
基础数据类型注解
# 基础数据类型注解
var_1: int = 10
var_2: str = "itheima"
var_3: bool = True
print(var_1)
print(var_2)
print(var_3)
10
itheima
True
类对象类型注解
# 类对象类型注解
class Student:
pass
stu: Student = Student()
基础容器类型注解
# 基础容器类型注解
my_list: list = [1, 2, 3]
my_tuple: tuple = (1, 2, 3)
my_dict: dict = {"itheima": 666}
# 容器类型详细注解
my_list: list[int] = [1, 2, 3]
my_tuple: tuple[int, str, bool] = (1, "itheima", True)
my_dict: dict[str, int] = {"itheima": 666}
在注释中进行类型注解
import random
import jason
#在注释中进行类型注解
var_1 = random.randint(1, 10) # type: int
var_2 = json.loads{'{"name": "zhangsan"}'} # type: dict
def func():
return 10
var_3 = func() # type: int
函数类型注解
def add(x: int, y: int) -> int:
return x + y
def func(data: list) -> list:
return data
注意:函数注解也是提示性的,所以以下代码不会报错
def add(x: int, y: int) -> int:
return x + y
def func(data: list) -> list:
return data
print(func(1))
Union类型
from typing import Union
my_list: list[Union[int, str]] = [1, 2, "itheima", "itcast"]
def func(data: Union[int, str]) -> Union[int, str]: # 函数返回Union类型
print(data)
func(1)
func("itheima")
1
itheima
数据分析案例步骤
每一条记录的定义
# 数据的封装
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):
return f"{self.date}, {self.order_id}, {self.money}, {self.province}"
读取JSON文件以及TEXT文件内的数据为recor对象,将这些record对象组装成一个list
# 设计一个抽象类,定义文件读取的相关功能,并使用子类实现具体功能读取文件
from data_define import record
import json
# 先定义一个抽象类用来做顶层设计,确定有哪些功能需要实现
class FileReader:
# 文件读取
def read_data(self) -> list[record]:
"""读取数据文件,读到的每一行数据都转化为record对象,将它们都封装到list内返回即可
:return:list[record]
"""
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")
lines = f.readlines()
record_list = []
for line in lines:
line = line.strip()
line = line.split(",")
record_list.append(record(line[0],line[1],int(line[2]),line[3]))
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] = []
lines = f.readlines()
for line in lines:
line = line.strip()
json_dict = json.loads(line)
record_list.append(record(json_dict['date'], json_dict['order_id'], json_dict['money'], json_dict['province']))
f.close()
return record_list
# 测试接口
if __name__ == "__main__":
text_file_reader = TextFileReader("C:/Users/18757/Desktop/pythontext/2011年1月销售数据.txt")
json_file_reader = JsonFileReader("C:/Users/18757/Desktop/pythontext/2011年2月销售数据JSON.txt")
l1 = text_file_reader.read_data()
l2 = json_file_reader.read_data()
for l in l1:
print(l)
for l in l2:
print(l)
"""
实现步骤:
1.设计一个类,可以完成数据的封装
2.设计一个抽象类,定义文件读取的相关功能,并使用子类实现具体功能读取文件
3.生产数据对象
4.进行数据需求的逻辑计算(计算每一天的销售额)
5.通过PyEcharts进行图形绘制
"""
from data_define import record
from file_define import FileReader, JsonFileReader, TextFileReader
January = TextFileReader("C:/Users/18757/Desktop/pythontext/2011年1月销售数据.txt").read_data()
Feburary = JsonFileReader("C:/Users/18757/Desktop/pythontext/2011年2月销售数据JSON.txt").read_data()
# 合并两个列表
sumlist = January + Feburary
# 求和计算每天对应的销售额
data_dict = {}
for r in sumlist:
if r.date not in data_dict.keys():
data_dict[r.date] = r.money
else:
data_dict[r.date] += r.money
for key in data_dict:
print(f"日期:{key},销售额是:{data_dict[key]}")
from data_define import record
from file_define import FileReader, JsonFileReader, TextFileReader
from pyecharts.charts import Bar
from pyecharts.options import LabelOpts,InitOpts,global_options,TitleOpts
from pyecharts.globals import ThemeType
January = TextFileReader("C:/Users/18757/Desktop/pythontext/2011年1月销售数据.txt").read_data()
Feburary = JsonFileReader("C:/Users/18757/Desktop/pythontext/2011年2月销售数据JSON.txt").read_data()
# 合并两个列表
sumlist = January + Feburary
# 求和计算每天对应的销售额
data_dict = {}
for r in sumlist:
if r.date not in data_dict.keys():
data_dict[r.date] = r.money
else:
data_dict[r.date] += r.money
# 构建柱状图
bar = Bar(init_opts=InitOpts(theme=ThemeType.LIGHT))
# 添加x轴的数据
bar.add_xaxis(list(data_dict.keys()))
# 添加y轴的数据
bar.add_yaxis("销售额",list(data_dict.values()),label_opts=LabelOpts(is_show=False))
bar.set_global_opts(title_opts=TitleOpts(title="每日销售额"))
bar.render(path="每日销售额柱状图.html")