01初识对象


本节学习参考链接
Python 中的类和对象_python类与对象的区别-CSDN博客
python入门(8)面向对象 :类、对象、属性与方法_python中的类和对象,属性和方法-CSDN博客



字典,字符串,列表,都可以存储信息。


案例代码------来自网上
python
class Hero: #定义类
def info(self) :#实例方法
print( "人生苦短,我用python")
#---------------------------------------------
Alex = Hero() # Hero这个类 实例化了一个对象Alex
Alex.info() # . 表示选择属性或者⽅方法



python
# 设计一个类,(类比生活中:设计一个表格)
class Student:
name = None
gender = None
nationality = None
native_place = None
age = None
# 以上是五个属性
# 创建一个对象() 这里的stu_1即是对象也是变量 基于类来创建对象
stu_1 = Student()
# 对象属性进行赋值(类比生活中填写表单) 通过对象,对具体的属性赋值,类似填表操作
# 通过对象来维护,组织数据。这种程序的写法,思路,比单纯的使用字符串,字典,列表更加的高效,更加的简洁明了。
# 这是良好的数据组织方法
stu_1.name = "王国瑞"
stu_1.gender = "男"
stu_1.nationality = "中国"
stu_1.native_place = "陕西省"
stu_1.age = 31
# 获取对象中记录的信息 查看stu_1是否真的能够存储数据。 通过print获取对象中记录的数据信息。
print(stu_1.name)
print(stu_1.gender)
print(stu_1.nationality)
print(stu_1.native_place)
print(stu_1.age)
# 这些信息是可以成功的被记录在对象的内部的。
使用对象,组织数据的思路。(本节讲的是这)
02-类的成员方法


看上图右边,类的具体对象
用类的具体对象,调用类内部提供的函数
类的行为(即写在类内部的函数)


改口了,哈哈。
类内部的方法,叫做成员方法。只要写成员方法,self关键字是必须存在的。

表示类对象自身的意思?

第三条,访问类的成员变量,必须使用self。



在定义类的时候,定义方法的时候,self必须要写。但是在传参使用的时候,忽略他的存在即可。

类中包含的两大部分。

03-类和对象








面向对象的编程,让对象干活。哈哈
python
class Clock:
id = None
price = None
def ring(self):
import winsound
winsound.Beep(2000, 3000) #
clock1 = Clock()
clock1.id = "003032"
clock1.price = 19.99
print(f"闹钟ID:{clock1.id}, 价格:{clock1.price}")
clock1.ring()
还真会响铃哈。

04-构造方法


所以,这就有意思了,构造类对象后,可以直接传参,因为上边有init方法存在,会自动执行参数。

参数提供给init方法使用。
上图,最后一行,------构造类对象的时候,顺手把成员变量的值给提供了。

成员变量,可以省略,不写的话,没有任何影响。
然后下面构造方法中的,self.name 等 是对成员变量进行声明,并且赋值。
只要是类里面的方法,不论是构造方法,还是普通的成员方法,都需要把self给带上。
self.name = name 外部传入的参数,赋值给成员变量,提供给内部的成员变量。



案例练习

python
class Information:
name = None
age = None
address = None
def __init__(self, name, age, address):
self.name = name
self.age = age
self.address = address
mylist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for i in mylist:
print(f"当前录入第{i}位学生信息,总共需要录入10位学生信息")
info = Information(input("请输入学生姓名:"), input("请输入学生年龄:"), input("请输入学生地址:"))
print(f"学生{i}信息录入完成,信息为:【学生姓名:{info.__init__},年龄{info.__init__}, 地址:{info.__init__}】")
自己写的,没有实现功能,,后续改进???
我下面这个能实现,但是用的不是构造方法。
python
class Information:
name = None
age = None
address = None
def __init__(self, name, age, address):
self.name = name
self.age = age
self.address = address
# mylist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for i in range(1, 10):
print(f"当前录入第{i}位学生信息,总共需要录入10位学生信息")
name = input("请输入学生姓名:")
age = input("请输入学生年龄:")
address = input("请输入学生地址:")
# info = Information(name, age, address)
print(f"学生{i}信息录入完成,信息为:【学生姓名:{name},年龄:{age}, 地址:{address}")
05-魔术方法/内置方法


掌握常见内置方法即可~



通过魔术方法,控制类对象,转变为字符串的行为。

python
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
# __str__ 魔术方法 很简单,就是你给我返回一个字符串就行。
def __str__(self):
return f"Student类对象,name:{self.name}, age: {self.age}"
stu = Student("周杰伦", 39)
print(stu)
print(str(stu))


python
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __lt__(self, other):
return self.age < other.age
stu1 = Student("周杰伦", 34)
stu2 = Student("林俊杰", 39)
print(stu1 < stu2)
print(stu1 > stu2)






06-封装







对于私有成员和变量,外部的类对象是不能使用的,但是类内部的其他成员是可以使用的。如上图。如下图。


这是不是说,外部的类对象,不能直接调用私有方法或变量,但是可以调用其他成员或方法,然后其他成员或方法,来调用这个私有的。也就是说,只要是我想成为私有的部分,外部顶多能用,但是看不到,用的时候,还得内部的先引用。???



07-封装的课后练习题讲解

私有成员的作用,不直接对用户开放私有的属性和方法。
python
class Phone:
__is_5g_enable = True
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()
# 下面是我写的代码
class Phone:
__is_5g_enable = 0
def __check_5g(self):
if __is_5g_enable == True:
print("5g开启")
else:
__is_5g_enable == False
print("5g关闭,使用4g网络")
def call_by_5g(self):
print("正在通话中")
08-继承的基础语法




pass关键字,进行补全。

有同名属性时,左边的父类优先。

这一节都是概念,没有代码练习。
09-复写父类成员和调用父类成员


即使复写之后,原来的父类中的属性和方法也是可以使用的。

10-变量的类型注解









通过注解,可以显而易见的知道,每个变量是什么类型。


两种注解方式,但是第一种用的比较多。


注解就相当于一个备注,写错也不会影响程序的运行。

类型注解用的多不多呢?
11-函数和方法的类型注解


函数(方法)注解,语法


对返回值进行类型注解,在冒号和括号之间写上如上部分。
这里的注解也是,属于提示性的,不是决定性的,即使写错,也不会影响代码的运行。

12-Union联合类型注解



对函数和变量都可以进行注解。

总结

13-多态

我咋感觉课程中的这个例子举的不是很好呢,以父类做定义声明,以子类做实际工作,用以获得同一行为,不同状态。我的理解,子类不就相当于对象了?类的实例化吗?还有就是,是不是可以获得不同行为的不同状态呢?
上边只是讲的多态的一个场景,下面是多态的另一个场景,即抽象类。

python
class Animal:
def speak(self):
pass
class Cat(Animal):
def speak(self):
print("喵喵喵")
class Dog(Animal):
def speak(self):
print("汪汪汪")
def make_noise(animal: Animal): # 这里表示同样的行为。后面引用这个函数后,传入不同的参数,就是不同的状态了。即多态。
animal.speak()
dog = Dog()
dog.speak() # 也可以输出汪汪汪
cat = Cat()
make_noise(dog)
make_noise(cat)

类比引入,由现实生活引入到程序中。
抽象类的作用:顶层抽象,顶层设计,就类似于生活中的标准,只是给出大概,不是具体实现,具体的由子类去实现。

这里配合多态,可完成多种状态的工作了。

python
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空调对象,使用AC类?
ac.cool_wind()
midea_ac = Midea_AC() # 构建子类的类对象。
gree_ac = GREE_AC()
make_cool(midea_ac)
make_cool(gree_ac)
抽象类,子类,与多态进行结合,可以实现,不同类,不同状态。
14-数据分析案例步骤------文件读取



纯文本格式,csv格式。


这个标识符很有意思啊。
15-数据分析案例步骤------数据计算
16-数据分析案例步骤------数据可视化
上面两节的笔记 合并在一起

构造类对象后,这里可以传参数。

课堂代码运行效果,我没有原始数据。

第三方库一般都有类型注解。


效果。
代码文件结构。

main文件
python
"""
面向对象,数据分析案例,主业务逻辑代码
实现步骤:
1,设计一个类,可以实现数据的封装
2,设计一个抽象的类,定义文件读取的相关功能,并使用子类实现具体功能
3,读取文件,生产数据对象
4,进行数据需求的逻辑计算(计算每一天的销售额)
5,通过PyEcharts 进行图形绘制
"""
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()
json_file_reader = JsonFileReader()
jan_data: list[Record] = text_file_reader.read_data()
feb_data: list[Record] = json_file_reader.read_data()
# 类型注解是Python 3.5版本引入的一项新功能,允许开发者在函数参数、变量和返回值等地方添加类型信息,以提高代码的可读性和可维护性。
# 类型注解并不会影响代码的实际执行,但可以通过类型检查工具如mypy等进行类型检查。
# 将2个月的数据合并为1个list来存储
all_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("每日销售额柱状图.html")
data.define文件
python
"""
定义数据类
"""
# 悟: 对于有两个子类,都需要继承某一个父类,然后两个子类都需要添加某一项功能的话,那么就将该功能添加到父类,让子类继承。
# 这个类的作用是,通过类来封装相应的数据
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.data}. {self.order_id}, {self.money}, {self.province}"
# 直接打印类,或者把他变成字符串,给的是其内存地址。但是给内存地址没有用,最好是给出直接的信息。
# 使用一种魔术方法,将字符串打印出来,而不是显示其地址。
# __str__() 这个魔术方法,可以解决打印出来不是内存地址的问题
file.define文件
python
"""
和文件相关的类定义
定义一个抽象类
"""
import json
# 先定义一个抽象类,用来做顶层设计,确定有哪些功能需要实现。
from data_define import Record # 从data_define 包里面导入Record类,类也可以导入哈。
class FileReader:
def read_data(self) -> list[Record]:
"""
读取文件的数据,读到的每一条数据都转换为Record对象,将他们都封装到list内返回即可
这段代码定义了一个函数 `read_data`,它接受一个 `self` 参数(通常用于类方法)并指定了返回类型注解为 `list[Record]`,表示函数会返回一个 `Record` 类型的列表。
这样的类型提示能够提供给阅读代码的人或者代码编辑器更多的信息,让他们知道这个函数返回的数据类型是什么,从而更好地理解和使用代码。
"""
class TextFileReader(FileReader):
def __init__(self, path): # 通过构造方法,来定义成员变量。
self.path = path # 定义自己的成员变量,记录成员变量,把外部的path传入进来。
def read_data(self) -> list[Record]: # 复写(实现抽象方法) 父类的方法
f = open(self.path, "r", encoding="UTF-8") # 在方法内部使用成员变量,千万不能忘记self。
record_list: list[Record] = [] # 定义一个容器,可以为空,下面用append方法进行添加即可。这里还可以添加一个类型注解。
for line in f.readlines():
line = line.strip() # 消除读取到的每一行数据中\n 换行操作,换行符
data_list = line.split(",") # 字符串里面的方法,分割文本
record = Record(data_list[0], data_list[1], data_list[2], data_list[3])
# 我的理解,这里是类的实例化,本python文件中导入了data_define中的抽象类,Record,然后传入了参数。
record_list.append(record)
f.close() # 在return之前,先进行close,要不然还得占用文件。
return record_list
class JsonFileReader(FileReader):
def __init__(self, path): # 通过构造方法,来定义成员变量。
self.path = path # 定义自己的成员变量,记录成员变量,把外部的path传入进来。
def read_data(self) -> list[Record]: # 把父类提供的抽象方法复写一下.
f = open(self.path, "r", encoding="UTF-8") # 在方法内部使用成员变量,千万不能忘记self。
record_list: list[Record] = [] # 定义一个容器,可以为空,下面用append方法进行添加即可。这里还可以添加一个类型注解。
for line in f.readlines():
data_dict = json.loads(line) # 通过json加载,直接加载就可以变成我们的字典对象,不用split切分了。 通过json.loads 可以把字符串转换成我们python的内部数据格式
record = Record(data_dict["data"], data_dict["order_id"], int(data_dict["money"]), data_dict["province"])
# 然后再把字典对象进行抽取,转换成record对象就可以了。
f.close()
return record_list
if __name__ == '__main__':
text_file_reader = TextFileReader("D:\论文阅读中的idea.text")
json_file_reader = JsonFileReader("")
list1 = text_file_reader.read_data()
list2 = json_file_reader.read_data()
for l in list1:
print(l)
for l in list2:
print(l)
补充学习:

类变量(Class Variables)是在类级别定义的变量,它们是与类本身相关联的变量,在整个类的所有实例之间共享。
实例变量(Instance Variables)是在类的实例化过程中为每个对象/实例单独创建的变量,而不是与整个类相关联的。
总结一下两者之间的区别:
- 类变量是与类本身相关联的变量,而实例变量是与类的实例(对象)相关联的变量。
- 类变量在整个类的所有实例之间共享,而实例变量是每个实例独有的。
- 类变量可以通过类名访问,而实例变量需要通过实例名或self关键字访问。

问题,backbone和特征网络?区别
