黑马程序员|8天Python第13章面向对象

一 初识对象

1.生活中数据的组织

2.程序中数据的组织

3.使用对象组织数据

类的属性: 


二 成员方法

1.类的定义和使用

2.成员变量和成员方法

类外面是函数,类里面是方法。 

3.成员方法的定义语法

self 只是写在这里,传参的时候可以当作不存在。 

4.注意

类名首字母一般大写。 

没有 student.name = "xxx" 就是默认的。



三 类和对象

1.现实世界的事务和类

现实世界中的事物可以分为两个特征:

 

2.类和对象

3.使用类和对象描述现实事物

在程序中通过类来描述。

4.基于类创建对象

面向对象编程就是让对象干活。 

# 类名大写
class Clock:
    id = None
    price = None

    def ring(self):
        # python 内置的模块,让电脑发出声音
        import winsound
        # 2000是频率,3000是响铃时间
        winsound.Beep(2000,3000)

# 构建干活的对象
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 = 199.99
print(f"闹钟ID:{clock2.id},价格:{clock2.price}")
clock2.ring()



四 构造方法

1.属性(成员变量)的赋值

通过传参的方式,把成员变量的值传进去。

2.构造方法

构造函数 __init__ 在创建类对象时自动执行,用于初始化对象的属性和设置初始状态。

stu 对象被创建时,Python 会自动调用 Student 类的 __init__ 方法。这个方法接受两个参数 agetel,并将它们赋值给对象的属性 self.ageself.tel

上面三行如果写了就是对成员变量的赋值,如果省略不写就是对成员变量进行声明并且赋值。

3.注意

不管什么方法,只要是类里面的方法,都必须带上 self 。

只要在类的方法中访问类成员变量都要通过 self 。

4.课堂练习

class Student :
    def __init__(self,name,age,adress):
        self.name = name
        self.age = age
        self.adress = name

for num in range(1,11):
    a = input("请输入学生姓名:")
    b = input("请输入学生年龄: ")
    c = input("请输入学生地址: ")
    stu = Student(a, b, c)
    print(f"学生{num}信息录入完成,信息为:【学生姓名:{stu.name},年龄:{stu.age},地址:{stu.adress}")
    print(f"当前录入第{num + 1}位学生信息,总共需录入10位学生信息")

 



五 其它内置方法

1.魔术方法

_str_字符串方法

这个魔术方法就是返回字符串,当我们需要把这个类的对象变成字符串,它就通过魔术方法的形式去获得要变成什么样的字符串,如果不写就输出内存地址,写了就输出你要的形式。

为什么不打印 return 的内容: 

print() 语句只显示 print() 内部的内容,而 return 语句返回的内容需要被显式地打印。

要同时打印 return 的内容,可以将 return 的结果传递给 print()

_It_小于符号比较方法

报错是因为当前类在定义的时候没有支持比较的功能,所以无法比较。

 _Ie_小于等于比较符号方法

 

_eq_比较运算符实现方法


六 封装

1.面向对象的三大特性

2.封装

3.对用户隐藏的属性和行为

4.私有成员

5.使用私有成员

如何定义私有成员:

上网前要检查手机的电压是否正常,开了程序需要程序调度,内存管理。

私有的东西不是给用户使用的,是给自己的功能使用的

6.课堂练习

用户不用管怎么检查5g,只管打电话就行了,所以把检查改成私有的。

class Phone :
    __is_5g_enable = False
    def __check_5g(self):
        if self.__is_5g_enable == True:
            print("5g开启")
        else:
            print("5g关闭,使用4g网络")
    def call_by_5g(self):
        self.__check_5g()
        print("正在通话中")

phone = Phone()
phone.call_by_5g()



七 继承

1.为什么有继承

2.单继承

3.多继承

4.注意

生父,养父,义父。 

写类的时候 class ...(...): 冒号里面不想写别的,可以用 pass ,表示空,功能只是补全语法。

5.复写

覆盖。

6.调用父类同名成员

变成只添加第1和3行的 print ,再直接调用父类的 print 。

多个父类指名点比较好。



八 类型注解

1.为什么要类型注解

是增加代码可读性的,加不加对程序没任何影响,只是方便人看。

2.什么是类型注解

3.类型注解的语法

因为 python 定义变量时不声明,才有了这些注解。

类 Student ,构建对象 stu 。

自己定义的时候可以看出来,但是代码一多起来自己就混乱了,目的是让 pycharm 在后面的使用过程中提示这个东西是什么类型的。

字典的注解第一个表示 key ,第二个表示 value 。

使用 random 要导包, 按 alt + 回车键可以自动搜索并导包。选 import this name 。

4.类型注解的限制

5.函数(方法)的类型注解

形参注解

ctrl + p 弹出提示

返回值注解

也是建议性的,不是决定性的。

6.Union 类型

什么是Union 类型

里面的数据不规则,有混合的类型。表示要么...类型要么...类型。

表示键是 str ,值可能是 str 也可能是 int 。

U要大写。

使用 Union 类型要先导包。

Union 的使用方式



九 多态

1.什么是多态

右边代码:函数接收了一个animal的对象,注解了类型是Animal,调用了animal对象的speak。传入的是子类对象。父类有speak方法,子类继承了父类。这些dog,cat是对象,不是变量。

再定义了两个子类的对象,没有传入父类对象,而是在调用这个函数的时候把dog和cat传进去,然后输出汪汪汪和喵喵喵。

传入不同的对象得到不同的输出,传入dog是汪汪汪,传入cat是喵喵喵。

要传入 animal 对象。

构建两个子类对象来调用这个函数。有两个子类的具体对象。

然后调用make_noise,要求传入Animal类型,但是不传入父类对象,而是传入两个具体的子类对象。

make_noise是函数,括号内是形参,填入对象就是调用speak方法了。

同样的行为 make_noise  使用不同的对象,获得不同的运行状态。

2.抽象类(接口)

什么是抽象类(接口)

抽象方法:方法体是空实现的。Animal类包含了抽象方法,所以叫抽象类。

 

抽象类(接口)的作用

AC 这个类并不是拿来直接使用的,不会获取 AC 的具体对象,作用是顶层设计。

真正工作的是 AC 的子类。第2列进行了复写才可以正常工作,因为父类什么也没写

抽象类是顶层代码,就是规划下面如何如何设计的,这个类没有什么功能,就是一个集合体,功能都由其子类去实现。

有了具体的子类,就可以完成多种状态的工作了,构建具体的子类对象,函数内传入子类对象去工作,同一个制冷行为,传入不同的对象,就得到不同的状态。

父类规范内容,以pass结束,等待子类实现具体功能。


十 综合案例

需求:每日销售额

只要将日期和对应的日期金额求和即可。

步骤1:

步骤2:文件读取

 使用抽象类的原因:有两份数据文件,第一份里面是标准的文本,通过逗号分隔数据。

 第2份数据是json。

文件不同,读取文件的具体实现逻辑也不一样,所以构建抽象类。

先在最顶级设计好读取文件应该有哪些基础功能,但是不实现,然后通过具体的子类(文本读取子类)( json 读取子类)来实现具体数据的具体读取方法。

抽象类的定义就是为多态的使用做准备,有不同的数据,但是要完成同样的行为而制定的统一规则,定义抽象类以后,通过子类来实现相同行为的不同内容

 如果不加这个 __str__ 方法,就会输出数据的内存地址。

因为如果一个类没有定义这两个方法,print() 函数将会输出对象的内存地址,而不是对象的实际内容。read_data()方法返回的是一个 record_list 列表,这个列表是通过每一次Record对象追加得到的,所以如果直接循环打印就会打印出内存地址。

加上__str__ :

输出内存地址的原因是 Record 类的 __str__ 方法没有被调用。

只能用 for 循环才能调用到Record 类的 __str__ 方法吗

步骤3:数据计算

from file_define import FileReader,TextFileReader,JsonFileReader
from data_define import Record

# 读取数据 read_data
text_file_reader = TextFileReader("D:/2011年1月销售数据.txt")
json_file_reader = JsonFileReader("D:/2011年2月销售数据JSON.txt")

one_data = text_file_reader.read_data() # type:list[Record]   
# list 类型,放的是 Record 对象
two_data = json_file_reader.read_data() # type:list[Record]

# 把两个月份的数据合并成一个 list
all_data = one_data + two_data  # type:list[Record]

# 数据计算 数据有日期,每一条都有销售额
# 把1号所有的销售额都取到,然后累加求个和
# 初始:{“2011-01-01”:0} ,然后 for 循环列表,把符合的和初始0相加
data_dict = {}
# 列表 all_data 里面每一个元素都是一个对象,date,order_id,money,province
for i in all_data : # record 是 Record 对象
    if i.date in data_dict.keys():
        # 当前日期已经有记录了,只要和老数据做累加即可
        # 取出老数据
        data_dict[i.date] += i.money
    else:
        # 还没有这个日期被记录
        data_dict[i.date] = i.money

# 最后字典 data_dict 里面就记录了每一天的销售额

print(data_dict)

步骤4:可视化 

from step3 import *  
from pyecharts.charts import Bar
# 柱状图
from pyecharts.options import *
# 选项
from pyecharts.globals import ThemeType
# 主题类型,图表颜色

# 构建类对象 通过 Bar 这个类得到类对象 bar
bar = Bar()
# 添加 x 轴数据:日期
# 需要传入 list
bar.add_xaxis(list(data_dict.keys()))
# 添加y轴
bar.add_yaxis("销售额",list(data_dict.values()))
# 给图表设置标题
bar.set_global_opts(
    title_opts=TitleOpts(title="每日销售额")
)
bar.render("每日销售额柱状图.html")

让 y 轴不要显示数字:

修改颜色:


(已解决)为什么只能写from step3 import * 才对。 

 

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值