乐趣区

关于python:八面向对象

面向对象

提醒:本文依据 b 站黑马 python 课整顿

链接指引 => 2022 新版黑马程序员 python 教程

一、初识对象

应用对象组织数据

在程序中是能够做到和生存中那样,设计表格、生产表格、填写表格的组织模式的。

  1. 在程序中 设计表格 ,咱们称之为: 设计类(class)

    class Student:
     name = None
  2. 在程序中 打印生产表格 ,咱们称之为: 创建对象

    # 基于类创建对象
    stu1 = Student()
    stu2 = Student()
  3. 在程序中 填写表格 ,咱们称之为: 对象属性赋值

    stu1.name = '111'
    stu2.name = '111'

二、成员办法

2.1 类的定义和应用

类的应用语法:

  • class 是关键字,示意要定义类了
  • 类的属性,即定义在类中的变量(成员变量)
  • 类的行为,即定义在类中的函数(成员办法)
class 类名称:
    类的属性
    类的行为

创立类对象的语法:

对象 = 类名称()

2.2 成员变量和成员办法

类中定义的属性(变量),咱们称之为:成员变量
类中定义的行为(函数),咱们称之为:成员办法

2.2.1 成员办法的定义语法

def 办法名(self, 行参 1, ..., 行参 n):
    办法体

能够看到,在办法定义的参数列表中,有一个:self关键字
self 关键字是成员办法定义的时候, 必须填写 的。

  • 它用来示意类对象本身的意思
  • 当咱们应用类对象调用办法的是,self 会主动被 python 传入
  • 在办法外部,想要拜访类的成员变量,必须应用 self
def say_hi(self):
    print(f"hi 大家好,我是{self.name}")

注意事项:self 关键字,只管在参数列表中,然而传参的时候能够疏忽它。

三、类和对象

基于类创建对象的语法: 对象名 = 类名称()

四、构造方法

Python 类能够应用:__init__()办法,称之为构造方法。

能够实现:

  • 在创立类对象(结构类)的时候,会主动执行。
  • 在创立类对象(结构类)的时候,将传入参数主动传递给__init__办法应用。

在构造方法内定义成员变量,须要应用 self 关键字

class Student:

    def __init__(self, name, age, address):
        self.name = name
        self.age = age
        self.address = address

stu = Student('天天', 30, '1111')

案例:

学生信息录入

# 学生信息录入
class Student:
    id = None
    name = None
    age = None
    address = None


    def insert (self, id, name, age, address):
        self.id = id
        self.name = name
        self.age = age
        self.address = address

        print(f'学生 {id} 信息录入实现,信息为:【学生姓名:{name},年龄:{age},地址:{address}】')

idx = 10
for i in range(0, idx):
    print(f'以后录入第 {i+1} 位学生信息,总共需录入 10 位学生信息')
    name = input('请输出学生姓名:')
    age = input('请输出学生年龄:')
    address = input('请输出学生地址:')

    stu = Student()
    stu.insert(i+1, name, age, address)

    if i+1 == 10:
        print('10 位学生信息录入结束!')

五、其它内置办法(魔术办法)

上文学习的__init__ 构造方法,是 Python 类内置的办法之一。
这些内置的类办法,各自有各自非凡的性能,这些内置办法咱们称之为:魔术办法

办法 性能
__init__ 构造方法,可用于创立类对象的时候设置初始化行为
__str__ 用于实现类对象转字符串的行为
__lt__ 用于 2 个类对象进行小于或大于比拟
__le__ 用于 2 个类对象进行小于等于或大于等于比拟
__eq__ 用于 2 个类对象进行相等比拟

5.1 __str__ 字符串办法

内存地址没有多大作用,咱们能够通过 __str__ 办法,管制类转换为字符串的行为。

  • 办法名:__str__
  • 返回值:字符串
  • 内容:自行定义
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}"

5.2 __lt__ 小于符号比拟办法 (__gt__ 大于符号比拟办法)

间接对 2 个对象进行比拟是不能够的,然而在类中实现 __lt__ 办法,即可同时实现:小于符号 和 大于符号 2 种比拟
比拟大于符号的魔术办法是:__gt__
不过,实现了 __lt____gt__ 就没必要实现了

  • 办法名:__lt__
  • 传入参数:other,另一个类对象
  • 返回值:True 或 False
  • 内容:自行定义

5.3 __le__ 小于等于比拟符号办法

魔术办法:__le__可用于:<=、>= 两种比拟运算符上。

  • 办法名:__le__
  • 传入参数:other,另一个类对象
  • 返回值:TrueFalse
  • 内容:自行定义

>=符号实现的魔术办法是:__ge__
不过,实现了 __le____ge__ 就没必要实现了

5.4 __eq__,比拟运算符实现办法

不实现 __eq__办法,对象之间能够比拟,然而是比拟内存地址,也即是:不同对象 == 比拟肯定是 False 后果

实现了 __eq__ 办法,就能够依照本人的想法来决定 2 个对象是否相等了。

  • 办法名:__eq__
  • 传入参数:other,另一个类对象
  • 返回值:TrueFalse
  • 内容:自行定义

六、封装

面向对象的三大个性

  • 封装
  • 继承
  • 多态

封装示意的是,将事实世界事物的:

  • 属性
  • 行为

封装到类中,形容为:

  • 成员变量
  • 成员办法

6.1 公有成员

既然事实事物有不公开的属性和行为,那么作为事实事物在程序中映射的类,也应该反对。

类中提供了公有成员的模式来反对。

  • 公有成员变量
  • 公有成员办法

定义公有成员的形式非常简单,只须要:

  • 公有成员变量:变量名以__结尾(2 个下划线)
  • 公有成员办法:办法名以__结尾(2 个下划线)
    即可实现公有成员的设置
class Phone:

    __is_5g_enable = False  # 公有成员变量

    def __check_5g(self):    # 公有成员办法
        print('5g 开启')

练习:
设计带有公有成员的手机

# 设计带有公有成员的手机
import random

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()
phone.call_by_5g()

a = random.randint(1,2)

七、继承

  1. 什么是继承?
    继承就是一个类,继承另外一个类的成员变量和成员办法
  2. 语法:

    • 子类构建的类对象,能够
    • 有本人的成员变量和成员办法
    • 应用父类的成员变量和成员办法
  3. 单继承和多继承
    单继承:一个类继承另一个类
    多继承:一个类继承多个类,依照程序从左向右顺次继承
    多继承中,如果父类有同名办法或属性,先继承的优先级高于后继承
  4. pass 关键字 的作用是什么
    pass 是占位语句,用来保障函数(办法)或类定义的完整性,示意无内容,空的意思

7.1 继承的根底语法

7.1.1 单继承

class 类名(父类名):
    类内容体

继承分为:单继承和多继承
应用如图语法,能够实现类的单继承。
继承示意:将从父类那里继承(复制)来成员变量和成员办法(不含公有

7.1.2 多继承

一个类,能够继承多个父

class 类名(父类 1,父类 2,...., 父类 n):
    类内容体

多继承注意事项:
    多个父类中,如果有同名的成员,那么默认以继承程序(从左到右)为优先级。

&nbsp;&nbsp;&nbsp;&nbsp; 即:先继承的保留,后继承的被笼罩

7.2 复写和应用父类成员

7.2.1 复写

复写:子类继承父类的成员属性和成员办法后,如果对其“不称心”,那么能够进行复写。
           即:在子类中从新定义同名的属性或办法即可。

class FileReader:

    def read_file(self):
        """读取文件的数据,读到的每一条数据都转换为 Record 对象,将他们封装到 list"""
        pass

# 文本文件的读取
class TextFileRead(FileReader):

    def __init__(self, path):
        self.path = path    # 定义文件门路
    
     # 复写父类的办法
    def read_file(self):
        print('11111')

7.2.2 调用父类同名成员

一旦复写父类成员,那么类对象调用成员的时候,就会调用复写后的新成员
如果须要应用被复写的父类的成员,须要非凡的调用形式:

形式 1:

  • 调用父类成员
  • 应用成员变量:父类名. 成员变量
  • 应用成员办法:父类名. 成员办法(self)

形式 2:

  • 应用 super() 调用父类成员
  • 应用成员变量:super(). 成员变量
  • 应用成员办法:super(). 成员办法()

只能在子类内调用父类的同名成员。
子类的类对象间接调用会调用子类复写的成员

八、类型注解

8.1 变量的类型注解

  1. 为变量设置类型注解
    根底语法:变量: 类型

留神:
元组类型设置类型具体注解,须要将每一个元素都标记进去
字典类型设置类型具体注解,须要 2 个类型,第一个是 key 第二个是 value

  1. 除了应用 变量: 类型,这种语法做注解外,也能够在正文中进行类型注解。
    语法:
    # type: 类型

8.2 函数(办法)的类型注解

函数和办法的形参类型注解语法:

def 函数办法名(形参名:类型,形参名:类型,.....):
    pass

同时,函数(办法)的返回值也是能够增加类型注解的。

语法如下:

def 函数办法名(形参名:类型,形参名:类型,.....) -> 返回值类型:
    pass
def read_file(x: int, y: int) -> list[int]:
    pass

8.3 Union 类型

Union 的应用形式:

  • 导包:from typing import Union
  • 应用:Union[类型, ……, 类型]

九、多态

多态,指的是:多种状态,即实现某个行为时,应用不同的对象会失去不同的状态。

9.1 抽象类(接口)

这种设计的含意是:

  • 父类用来确定有哪些办法
  • 具体的办法实现,由子类自行决定

抽象类:含有形象办法的类称之为抽象类
形象办法:办法体是空实现的(pass)称之为形象办法

抽象类的作用

  • 多用于做顶层设计(设计标准),以便子类做具体实现。
  • 也是对子类的一种软性束缚,要求子类必须复写(实现)父类的一些办法
  • 并配合多态应用,取得不同的工作状态。

十、案例

数据分析案例

main.py

"""面向对象,数据案例剖析"""
from pyecharts.charts import Line, Bar
from pyecharts.options import *
from pyecharts.globals import ThemeType

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

text_file_reader = TextFileRead('./data/2011 年 1 月销售数据.txt')
json_file_reader = JsonFileReader('./data/2011 年 2 月销售数据 JSON.txt')

jan_data: list[Record] = text_file_reader.read_file()
feb_data: list[Record] = json_file_reader.read_file()

# 将两个月份的数据合并为一个 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('每日销售额 echarts.html')

file_defined.py

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

from data_define import Record

class FileReader:

    def read_file(self) -> list[Record]:
        """读取文件的数据,读到的每一条数据都转换为 Record 对象,将他们封装到 list"""
        pass


# 文本文件的读取
class TextFileRead(FileReader):

    def __init__(self, path):
        self.path = path    # 定义文件门路

    # 复写父类的办法
    def read_file(self) -> list[Record]:
        f = open(self.path, 'r', encoding="UTF-8")

        record_list: list[Record] = []
        for line in f.readlines():
            line = line.strip() # 打消空格和换行
            data_list = line.split(',')
            record = Record(data_list[0], data_list[1], int(data_list[2]), data_list[3])
            record_list.append(record)
            # print(record_list)

        f.close()
        return record_list


# Json 文件的读取
class JsonFileReader(FileReader):

    def __init__(self, path):
        self.path = path    # 定义文件门路

    def read_file(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 = TextFileRead('./data/2011 年 1 月销售数据.txt')
    text_json = JsonFileReader('./data/2011 年 2 月销售数据 JSON.txt')
    list1 = text_file.read_file()
    list2 = text_json.read_file()

    for l in list1:
        print(l)

    for l in list2:
        print(l)

data_defined.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}"

总结

以上就是 python 向对象,之后会继续更新,欢送大家点赞关注呀~~

退出移动版