第二章、面向对象(黑马笔记)

  1. 初识对象

1.生活中或是程序中,我们都可以使用设计表格、生产表格、填写表格的形式组织数据

2.进行对比,在程序中:

  • 设计表格,称之为:设计 (class)

  • 打印表格,称之为;创建对象

  • 填写表格,称之为:对象属性赋值

第二章、面向对象(黑马笔记)_第1张图片
# 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 = 18
# 4. 获取对象中记录的信息
print(stu_1.name)
print(stu_1.gender)
print(stu_1.nationality)
print(stu_1.native_place)
print(stu_1.age)
  1. 成员方法

1.类是由哪两部分组成呢?

  • 类的属性,称之为:成员变量

  • 类的行为,称之为:成员方法

注意:函数是写在类外的,定义在类内部,我们都称之为方法

  1. 类和成员方法的定义语法

class 类名称:
    成员变量
    def 成员方法(self,参数列表):
        成员方法体

对象 = 类名称()

3.self的作用

  • 表示类对象本身的意思

  • 只有通过self,成员方法才能访问类的成员变量

  • self出现在形参列表中,但是不占用参数位置,无需理会

# 定义一个带有成员方法的类
class Student:
    name = None

    def say_hi(self):
        print(f"你好,我是{self.name}")

    def say_hi(self,msg):
        print(f"你好,我是{self.name},{msg}")

stu = Student()
stu.name = "李华"
stu.say_hi("good moring")

stu2 = Student()
stu2.name = "李华2"
stu2.say_hi("good evening")
  1. 类和对象

1.现实世界的事物由什么组成?

  • 属性

  • 行为

类也可以包含属性和行为,所以使用类描述现实世界事物是非常合适的

2.类和对象的关系是什么?

类是程序中的“设计图纸

对象是基于图纸生产的具体实体

3.什么是面向对象编程?

面向对象编程就是,使用对象进行编程。

即,设计类,基于类创建对象,并使用对象来完成具体的工作

# 定义一个闹钟类
class Clock:
    id = None
    price = None

    def ring(self):
        import winsound
        winsound.Beep(2000, 3000)

# 构建两个闹钟对象并让其工作
clock1= Clock()
clock1.id = "001"
clock1.price = 39.9
print(f"闹钟ID:{clock1.id},价格:{clock1.price}")
clock1.ring()    # 响铃警告!!!!!!
  1. 构造方法

构造方法注意事项

1.构造方法的名称是:

__init__ , 注意init前后的2个下划线符号

2.构造方法的作用

  • 构建类对象的时候会自动运行

  • 构建类对象的传参会传递给构造方法,借此特性可以给成员变量赋

3.注意事项:

  • 构造方法不要忘记self关键字

  • 在方法内使用成员变量需要使用self

# 使用构造方法对成员变量进行赋值
# 构造方法名称:__init__

class Student:

    def __init__(self,name,age,tel):
        self.name = name
        self.age = age
        self.tel = tel
        print("Student类创造了一个类对象")

stu = Student("李华", 18, "13866665555")
print(stu.name,stu.age,stu.tel)
  1. 其他内置方法

第二章、面向对象(黑马笔记)_第2张图片
"""
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}"

    # __lt__魔术方法
    def __lt__(self,other):
        return self.age < other.age

    # __le__魔术方法
    def __le__(self,other):
        return self.age <= other.age

    # __eq__魔术方法
    def __eq__(self, other):
        return self.age == other.age

stu1 = Student("lihua", 18)
stu2 = Student("zhangsan", 20)
print(stu1 < stu2)
print(stu1 >= stu2)
print(stu1 == stu2)
  1. 封装

1.封装的概念是指?

将现实世界事物在类中描述为属性和方法,即为封装。

2.什么是私有成员?为什么需要私有成员?

现实事物有部分属性和行为是不公开对使用者开放的。同样在类中描述属性和方法的时候也需要达到这个要求,就需要定义私有成员了

3.如何定义私有成员?

成员变量和成员方法的命名均以 作为开头即可

4私有成员的访问限制?

  • 类对象无法访问私有成员

  • 类中的其它成员可以访问私有成员

"""
设计带有私有成员的手机
"""
class Phone:
    __is_5g_enable = False

    # 提供私有成员方法:__check_5g()
    def __check_5g(self):
        if self.__is_5g_enable:
            print("5g开启")
        else:
            print("5g关闭,使用4g")

    # 提供公开成员方法:call_by_5g()
    def call_by_5g(self):
        self.__check_5g()
        print("正在通话中")

phone = Phone()
phone.call_by_5g()

  1. 继承

1.什么是继承?

继承就是一个类,继承另外一个类的成员变量和成员方法

语法:

class 类(父类[,父类,....., 父类N]):
    类内容体

子类构建的类对象,可以

  • 有自己的成员变量和成员方法

  • 使用父类的成员变量和成员方法

2.单继承和多继承

单继承:一个类继承另一个类

多继承:一个类继承多个类,按照顺序从左向右依次继承

多继承中,如果父类有同名方法或属性,先继承的优先高于后继承

3.pass关键字的作用是什么

pass是占位语句,用来保证函数(方法)或类定义的完整性,表示无内容,空的意思

# 单继承
class Phone:
    producer = "VIVO"

    def call_by_4g(self):
        print("4g通话")

class Phone2022(Phone):
    face_id = "001"

    def call_by_5g(self):
        print("新增5g通话")

phone = Phone2022()
print(phone.producer)
phone.call_by_4g()
phone.call_by_5g()

# 多继承

class Phone:
    IMEI = None
    producer = "VIVO"

    def call_by_5g(se1f):
        print("5g通话")

class NFCReader:
    nfc_type = "第五代"
    producer = "HUAWEI"

    def read_card(se1f):
        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_5g()
phone.read_card()
phone.write_card()
phone.control()

复写父类成员和调用父类成员

1.复写表示

对父类的成员属性或成员方法进行重新定义

2.复写的语法

在子类中重新实现同名成员方法或成员属性即可

3.在子类中,如何调用父类成员

方式1:

  • 调用父类成员

使用成员变量:父类名.成员变量

使用成员方法:父类名.成员方法(self)

方式2:

  • 使用super()调用父类成员

使用成员变量: super().成员变量

使用成员方法:super().成员方法()

  • 注意:只可以在子类内部调用父类的同名成员,子类的实体类对象调用默认是调用子类复写的

class Phone:
    producer = "HUAWEI"

    def call_by_5g(self):
        print("使用5g网络")

# 定义子类,复写父类成员
class MyPhone(Phone):
    producer = "HONOR"

    def call_by_5g(self):
        print("开启CPU单核模式,在通话时省电")
        print(f"父类的厂商是:{Phone.producer}")       # 方法一: 父类名.成员变量
        print(f"父类的厂商是:{super().producer}")     # 方法二: super().成员变量
        Phone.call_by_5g(self)      # 方法一: 父类名.成员方法(self)
        super().call_by_5g()        # 方法二: super().成员方法()
        print("关闭CPU单核模式,确保性能")

phone = MyPhone()
phone.call_by_5g()
print(phone.producer)
  1. 类型注解

变量的类型注解

1.什么是类型注解,有什么作用?

在代码中涉及数据交互之时,对数据类型进行显式的说明,可以帮助:

  • PyCharm等开发工具对代码做类型推断协助做代码提示

  • 开发者自身做类型的备注

2.类型注解支持:

  • 变量的类型注解

  • 函数(方法)的形参和返回值的类型注解

3.变量的类型注解语法

  • 语法1: 变量:类型

  • 语法2: 在注释中,# type: 类型

4.注意事项

  • 类型注解只是提示性的,并非决定性的。数据类型和注解类型无法对应也不会导致错误

"""
变量的类型注解
"""
import json
import random

# 基础数据类型注解
var_1: int = 10
var_2: str = "abc"
var_3: bool = True
# 类对象类型注解
class Student:
    pass
stu: Student = Student()

# 基础容器类型注解
my_list: list = [1, 2, 3]
my_tuple: tuple = (1, 2, 3)
my_dict: dict = {"abc": 123}
# 容器类型详细注解
my_list: list[int] = [1, 2, 3]
my_tuple: tuple[int, str, bool] = (1, "abc", True)
my_dict: dict[str, int] = {"abc", 123}
# 在注释中进行类型注解
var_1 = random.randint(1, 10)           # type: int
var_2 = json.loads('{"name": "abc"}')   # type: dict[str,str]
def func():
    pass
var_3 = func()      # type: int
# 类型注释的限制

*函数和方法类型注解

1函数(方法)可以为哪里添加注解?

  • 形参的类型注解

  • 返回的类型注解

  1. 函数(方法)的类型注解语法?

def 函数方法名(形参:类型,......, 形参:类型) -> 返回值类型:
    pass

注意,返回值类型注解的符号使用: ->

"""
对函数(方法)进行类型注解
"""
def add(x: int, y: int):
    return x + y

# 对返回值进行类型注解
def func(data: list) -> list:
    return data

print(func(1))

*Union类型注解

1.什么是Union类型?

使用Union可以定义联合类型注解

2.Union的使用方式

  • 导包: from typing import Union

  • 使用:Union[类型,......, 类型]

"""
Unoin联合类型注解
"""
# 使用Union类型,需先导包
from typing import Union

my_list: list[Union[int, str]] = [1, 2, "abc"]

def func(data: Union[int, str]) -> Union[int, str]:
    pass

func()      # ctrl + p 查看可用类型

  1. 多态

1.什么是多态?

多态指的是,同一个行为,使用不同的对象获得不同的状态。

如,定义函数(方法),通过类型注解声明需要父类对象,实际传入子类对象进行工作,从而获得不同的工作状态

2.什么是抽象类(接口)

包含抽象方法的类,称之为抽象类。抽象方法是指: 没有具体实现的方法(pass)称之为抽象方法

3.抽象类的作用

多用于做顶层设计(设计标准),以便子类做具体实现。

也是对子类的一种软性约束,要求子类必须复写(实现)父类的一些方法并配合多态使用,获得不同的工作状态。

"""
面向对象的多态特性以及抽象类(接口)的使用
"""

class Animal:
    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        print("wolf")

class Cat(Animal):
    def speak(self):
        print("mio")

def make_noise(animal: Animal):
    """制造噪音,需要传入Animal对象"""
    animal.speak()

# 演示多态,使用两个子类对象来调用函数
dog = Dog()
cat = 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()

midea_ac = Midea_AC()
gree_ac = GREE_AC()

make_cool(midea_ac)
make_cool(gree_ac)

  1. 综合案例

第二章、面向对象(黑马笔记)_第3张图片
第二章、面向对象(黑马笔记)_第4张图片

data_define.py文件

"""
数据定义的类
"""

class Record:

    def __init__(self,data, order_id, money, province):
        self.date = data                # 订单日期
        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}"

file_defin.py文件

"""
和文件相关的类定义
"""
import json

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 JosnFileReader(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("D:/BaiduNetdiskDownload/资料/2011年1月销售数据.txt")
    json_file_reader = JosnFileReader("D:/BaiduNetdiskDownload/资料/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)

main.py文件

"""
面向对象,数据分析案例,主业务逻辑代码
实现步骤:
1. 设计一个类,可以完成数据的封装
2. 设计一个抽象类,定义文件读取的相关功能,并使用了类实现具体功能
3. 读取文件,生产数据对象
4. 进行数据需求的逻辑计算(计算每一天的销售额)
5. 通过PyEcharts进行图形绘制
"""

from file_define import FileReader, TextFileReader, JosnFileReader
from data_define import Record
from pyecharts.charts import Bar
from pyecharts.options import *
from pyecharts.globals import ThemeType
import os

text_file_reader = TextFileReader("D:\BaiduNetdiskDownload\资料/2011年1月销售数据.txt")
json_dile_reader = JosnFileReader("D:\BaiduNetdiskDownload\资料/2011年2月销售数据JSON.txt")

jan_data: list[Record] = text_file_reader.read_data()
feb_data: list[Record] = json_dile_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():
        # 当前日期已经有记录了,故和老记录做累加即可
        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")
os.system("每日销售额.html")

运行结果

第二章、面向对象(黑马笔记)_第5张图片

你可能感兴趣的:(python)