Python面向对象笔记

一、初始对象

使用对象组织数据

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

    class Student
    	name = None   # 记录学生姓名
    
  2. 在程序中打印生产表格,我们称之为:创建对象

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

    stu_1.name = "张三"	# 为学生1对象赋予名称属性值
    stu_2.name = "李四"	# 为学生1对象赋予名称属性值
    

二、成员方法

1.类的定义和使用

class 类名称:		# class是关键字,表示要定义类了
    类的属性		# 类的属性,即定义在类中的变量(成员变量)
    类的行为		# 类的行为,即定义在类中的函数(成员方法)
创建类对象的语法:对象 = 类名称()

2.成员变量和成员方法

class Student:
    name = None
    age = None

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


stu = Student()
stu.say_hi() # 输出:Hi大家好,我是None

定义在类内部的函数叫方法

3.成员方法的定义语法

  • 在类中定义成员方法和定义函数基本一致,有细微之分:

    def 方法名(self, 形参1..., 形参n):
    	方法体
    

    self关键字是成员方法定义的时候,必须填的

    • 他用来表示类对象自身的意思
    • 当我们使用类对象调用方法的时候,self会自动被python传入
    • 在方法内部,想要访问类的成员变量,必须使用self

4.注意事项

  • self关键字,尽管在参数列表中,但是传参的时候可以忽略它
class Student:
    name = None

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

    def say_hi2(self, msg):
        print(f"很高兴认识大家,{msg}")


stu = Student()
stu.say_hi()
stu.say_hi2("很高兴认识大家")

三、类和对象

1.类和对象

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

    class Clock:
        id = None
        price = None
    
        def ring(self):
            import winsound
            winsound.Beep(2000, 3000)
    
    
    clock1 = Clock()
    clock1.id = "003"
    clock1.price = 19.9
    print(f"闹钟ID:{clock1.id},价格:{clock1.price}")
    clock1.ring()
    
    clock2 = Clock()
    clock2.id = "004"
    clock2.price = 29.9
    print(f"闹钟ID:{clock2.id},价格:{clock2.price}")
    clock2.ring()
    

四、构造方法

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

  • class Student:
        name = None
        age = None
    	tel = None
    
    student1 = Student()
    student1.name = "张三"
    student1.age = 20
    student1.tel = "15547896547"
    
    student2 = Student()
    student2.name = "admin"
    student2.age = 29
    student2.tel = "15337896547"
    

2. 构造方法

python类可以使用:_ _ 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


student1 = Student("张三", 18, "15547852536")

3.构造方法注意事项

  • init前后都有两个下划线_ _init _ _

  • 构造方法也是成员方法,参数列表中也有:self

  • 在构造方法内定义成员变量,需要使用self关键字

    变量是定义在构造方法内部,如果要成为成员变量,需要用self来表示

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

五、其他内置方法

魔术方法:内置的类方法,各有各自特殊的功能,这些内置方法称为魔术方法

1._ _ 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("admin", 30)
print(stu)          # 输出:Student类对象,name:admin, age:30
print(str(stu))     # 输出:Student类对象,name:admin, age:30

2._ _ 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("admin", 30)
stu2 = Student("root", 20)
print(stu1 < stu2)  # 输出:False
print(stu1 > stu2)  # 输出:True

3._ _ 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("admin", 30)
stu2 = Student("root", 20)

print(stu1 <= stu2)     # 输出:False
print(stu1 >= stu2)     # 输出:True

4._ _ 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("admin", 30)
stu2 = Student("root", 30)

print(stu1 == stu2)     # 输出:True

六、封装

1. 面向对象的三大特性

基于模板(类)去创建实体(对象),使用对象完成功能开发

  1. 封装
  2. 继承
  3. 多态

2. 封装

封装就是将现实世界事物的属性和方法,封装到类中,描述为成员变量和成员方法,从而完成程序对现实事物的描述

私有成员

  • 私有成员变量

    变量名以_ _开头(两个下划线)

  • 私有成员方法

    方法名_ _开头(两个下划线)

使用私有成员

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

七、继承

1. 继承

# 单继承
class 类名(父类名):
	类内容体
    
# 多继承
class 类名(父类1, 父类2..., 父类n):
    类内容体
  • 单继承

    class Phone:
        IMEI = None
        producer = None
    
        def call_by_4g(self):
            print("4g通话")
    
    
    class Phone2022(Phone):
        face_id = True
    
        def call_by_5g(self):
            print("2022最新5g通话")
    
    
    phone = Phone2022()
    print(phone.IMEI)
    phone.call_by_4g()
    phone.call_by_5g()
    
  • 多继承

    class Phone:
        IMEI = None
        producer = None
    
        def call_by_4g(self):
            print("4g通话")
    
    
    class NFCReader:
        nfc_type = "第五代"
        producer = "HM"
    
        def read_card(self):
            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_4g()
    phone.read_card()
    phone.write_card()
    phone.control()
    

    注意事项:

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

    即:先继承的保留,后继承的被覆盖

  • pass关键字

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

2. 复写

子类继承父类的成员属性和成员方法后,如果对其“不满意”,那么可以进行复写,即:在子类中重新定义同名的属性或方法即可。

class Phone:
    IMEI = None         # 序列号
    producer = "INT"     # 厂商

    def call_by_5g(self):
        print("父类的5g通话")


class MyPhone(Phone):
    producer = "MI"     # 复写父类的成员属性

    # 复写父类的成员方法
    def call_by_5g(self):
        print("开启5g模式")
        

phone = MyPhone()
print(phone.producer)

3. 调用父类同名成员

一旦复写父类成员,那么类对象调用成员的时候,就会调用复写后的新成员。如果需要使用被复写的父类方法,需要特殊的调用方法:

  • 方式一:调用父类成员

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

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

  • 方式二:使用super()调用父类成员

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

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

八、类型注解

1. 类型注解

主要功能:

  • 帮助第三方IDE工具(如pycharm)对代码进行类型推断,协助做代码提示
  • 帮助开发者自身对变量进行注释

支持:

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

类型注解的语法:

  • 为变量设置类型注解(基础语法: 变量: 类型)
    # 基础数据类型注解
    var_1: int = 10
    var_2: float = 3.1415926
    var_3: bool = True
    var_4: str = "admin"
    
    
    # 类对象类型注解
    class Student:
        pass
    
    
    stu: Student = Student()
    
  • 容器类型注解
    # 基础容器类型注解
    my_list: list = [1, 2, 3]
    my_tuple: tuple = (1, 2, 3)
    my_set: set = {1, 2, 3}
    my_dict: dict = {"admin": 123456}
    my_str: str = "admin"
    # 容器类型详细注解
    my_list: List[int] = [1, 2, 3]
    my_tuple: Tuple[int, str, bool] = (1, "admin", True)	# 需要将每一个元素都标记出来
    my_set: Set[int] = {1, 2, 3}
    my_dict: Dict[str, int] = {"admin": 123456}				# 第一个是key,第二个是value
    
  • 除了使用变量:类型,语法注解外,也可以在注释中进行类型注解

    语法: # type:类型

  • 注意:

    一般,无法直接看出变量类型时会添加变量的类型注解

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

  • 形参注解

    def 函数方法名(形参名:类型, 形参名:类型,......):
        pass
    
    # 例如:
    def add(x: int, y: int):
        return x + y
    add(1, 2)
    
  • 返回值注解

    def 函数方法名(形参名:类型, 形参名:类型,......) -> 返回值类型:
        pass
    
    # 例如:
    def func(data: list) -> list:
        return data
    

3. Union类型注解

  • 使用Union[类型, …, 类型],可以定义联合类型注解

    from typing import Union, Dict
    
    my_dict: Dict[str, Union[str, int]] = {"name": "admin", "age": 20}
    
  • Union联合类型注解,在变量注解、函数(方法)形参和返回值注解中,均可使用。

    from typing import Union, Dict, List
    
    my_list: List[Union[int, str]] = [1, 2, "admin", "admin"]
    my_dict: Dict[str, Union[str, int]] = {"name": "admin", "age": 20}
    
    
    def func(data: Union[int, str]) -> Union[int, str]:
        pass
    

九、多态

1.多态

多态是指:多种状态,即完成某个行为时,使用不同的对象会得到不同的状态

同样的行为(函数),传入不同的对象,得到不同的状态

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)

2. 抽象类(接口)

含义是:

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

抽象类:含有抽象方法的类称之为抽象类(抽象类就好比定义一个标准,包含了一些抽象的方法,要求子类必须实现)

抽象方法:方法体是空实现(pass)称之为抽象方法

class AC:
    def cool_wind(self):
        """制冷"""
        pass

    def hot_wind(self):
        """制热"""
        pass

    def swing_wind(self):
        """左右摆风"""
        pass


class Mide_AC(AC):
    def cool_wind(self):
        print("美的空调核心制冷科技")

    def hot_wind(self):
        print("美的空调电热丝加热")

    def swing_wind(self):
        print("美的空调无风感左右摆风")


class GREE_AC(AC):
    def cool_wind(self):
        print("格力空调变频省电制冷")

    def hot_wind(self):
        print("格力空调电热丝加热")

    def swing_wind(self):
        print("格力空调静音左右摆风")


def make_cool(ac: AC):
    ac.cool_wind()


midea_ac = Mide_AC()
gree_ac = GREE_AC()

make_cool(gree_ac)	# 格力空调变频省电制冷
make_cool(midea_ac)	# 美的空调核心制冷科技

十、综合案例

  • main.py

    """
    1. 设计一个类,可以完成数据的封装
    2. 设计一个抽象类,定义文件读取的相关功能,并使用子类实现具体功能
    3. 读取文件,生产数据对象
    4. 进行数据需求的逻辑计算(计算每一天的销售额)
    5. 通过pyecharts进行图形绘制
    """
    from typing import List
    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("2011年1月销售数据.txt")
    json_file_reader = JsonFileReader("2011年2月销售数据JSON.txt")
    
    jan_data: List[Record] = text_file_reader.read_data()
    feb_data: List[Record] = json_file_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():
            # 当前日期有记录,可累计money
            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")
    
  • file_define.py

    """
    和文件相关的类定义
    """
    import json
    from typing import List
    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 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] = []
            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("2011年1月销售数据.txt")
        json_file_reader = JsonFileReader("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)
    
  • data_define.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}"
    
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值