首页 > 编程语言 >10.Python 对象(封装、继承、多态、类型注解)

10.Python 对象(封装、继承、多态、类型注解)

时间:2024-10-14 14:49:57浏览次数:3  
标签:__ 10 name Python self 多态 print age def

一、初始对象

  • 在程序中是可以做到和生活中那样,设计表格、生产表格、填写表格的组织形式的
  1. 在程序中设计表格,称之为设计类(class)
class Student:
    name: None
  1. 在程序中打印生产表格,称之为创建对象
stu1 = Student()
stu2 = Student()
  1. 在程序中填写表格,称之为对象属性赋值
stu1.name = "jack"
stu2.name = "tom"

二、类与对象

1、类的定义和使用
  1. 类的定义
class 【类】:
    【类的属性】

    【类的行为】
-说明
class关键字,表示要定义类
类的属性定义在类中的变量(成员变量)
类的行为定义在类中的函数(成员方法)
  1. 创建类对象
【对象】 = 类()
  1. 成员方法的定义
def 【方法】(self, 【形参 1】, 【形参 2】...):
    【方法体】
  • 在方法定义的参数列表中,有一个 self 关键字,它是成员方法定义的时必须填写的,用来表示类对象自身的意思,当使用类对象调用方法的是,self 会自动被 Python 传入(即可以忽略),在方法内部,想要访问类的成员变量,必须使用 self
2、演示
  1. 演示代码 1
class Student:
    name: None

    def sayHi(self):
        print(f"Hello,我是 {self.name}")

    def sayMsg(self, msg):
        print(f"Hello,{msg}")

stu = Student()
stu.name = "jack"
stu.sayHi()
stu.sayMsg("今天天气不错")
  • 输出结果
Hello,我是 jack
Hello,今天天气不错
  1. 演示代码 2
class Clock:
    id = None # 编号
    price = None # 价格

    def ring(self):
        print(f"闹钟 {self.id} 响铃了")

clock1 = Clock()
clock1.id = "001"
clock1.price = 10

clock2 = Clock()
clock2.id = "002"
clock2.price = 20

clock1.ring()
clock2.ring()
  • 输出结果
闹钟 001 响铃了
闹钟 002 响铃了

三、类的成员方法

1、构造方法
(1)基本介绍
  • Python 类可以使用 __init__ 方法,它是构造方法
  1. 在创建类对象(构造类)的时候,构造方法会自动执行

  2. 在创建类对象(构造类)的时候,Python 将传入参数自动传递给 __init__ 方法使用

  3. 构造方法也是成员方法,不要忘记在参数列表中提供 self,变量定义在构造方法内部,如果要成为成员变量,需要用 self 来表示

(2)演示
class Student:
    name = None
    age = None
    address = None

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

    def showInfo(self):
        print(f"{self.name}, {self.age}, {self.address}")

stu = Student("jack", 20, "地球")
stu.showInfo()
  • 输出结果
Student 类创建了一个对象
jack, 20, 地球
2、其他内置方法
  • __init__ 方法,是 Python 类内置的方法之一,这些内置的类方法,各自有各自特殊的功能,这些内置方法我们称之为魔术方法
(1)__str__ 方法
  1. 当类对象需要被转换为字符串时,默认会输出内存地址
class Student:
    name = None
    age = None
    address = None

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

stu = Student("jack", 20, "地球")
print(stu)
print(str(stu))
  • 输出结果
<__main__.Student object at 0x000001DFE0D00FD0>
<__main__.Student object at 0x000001DFE0D00FD0>
  1. 内存地址没有多大作用,可以通过 __str__ 方法,控制类转换为字符串的行为
class Student:
    name = None
    age = None
    address = None

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

    def __str__(self):
        return f"Student: name={self.name}, age={self.age}, address={self.address}"

stu = Student("jack", 20, "地球")
print(stu)
print(str(stu))
  • 输出结果
Student: name=jack, age=20, address=地球
Student: name=jack, age=20, address=地球
(2)__lt__ 方法
  1. 直接对 2 个对象进行比较是非法的
class Student:
    name = None
    age = None
    address = None

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

stu1 = Student("jack", 20, "地球")
stu2 = Student("tom", 15, "地球")

print(stu1 < stu2)
print(stu1 > stu2)
  • 输出结果
TypeError: '<' not supported between instances of 'Student' and 'Student'
  1. 在类中实现 __lt__ 方法,可同时完成小于和大于两种比较
class Student:
    name = None
    age = None
    address = None

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

    def __lt__(self, other):
        return self.age < other.age

stu1 = Student("jack", 20, "地球")
stu2 = Student("tom", 15, "地球")

print(stu1 < stu2)
print(stu1 > stu2)
  • 输出结果
False
True
(3)__gt__ 方法
  • 比较大于符号的是 __gt__ 方法,不过,实现了 __lt__ 方法,__gt__ 方法就没必要实现了
(4)__le__ 方法
  • __le__ 方法可用于小于等于和大于等于两种比较上
class Student:
    name = None
    age = None
    address = None

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

    def __le__(self, other):
        return self.age <= other.age

stu1 = Student("jack", 20, "地球")
stu2 = Student("tom", 15, "地球")

print(stu1 <= stu2) # False
print(stu1 >= stu2) # True
(5)__ge__ 方法
  • 比较大于等于符号的是 __ge__ 方法,不过,实现了 __le__ 方法,__ge__ 方法就没必要实现了
(6)__eq__ 方法
  1. 对象之间可以比较,但是默认是比较内存地址,也就是不同对象比较结果一定是 False
class Student:
    name = None
    age = None
    address = None

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

stu3 = Student("mary", 30, "地球")
stu4 = Student("smith", 30, "地球")

print(stu1 == stu2)
  • 输出结果
False
  1. 实现 __eq__ 方法就可以按照自己的方式来决定两个对象是否相等
class Student:
    name = None
    age = None
    address = None

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

stu3 = Student("mary", 30, "地球")
stu4 = Student("smith", 30, "地球")

print(stu1 == stu2)
  • 输出结果
True

四、封装

1、基本介绍
  • 封装表示的是将现实世界事物的属性和行为封装到类中,描述为成员变量和成员方法,从而完成程序对现实世界事物的描述

  • 现实世界中的事物,有属性和行为,但是不代表这些属性和行为都是开放给用户使用的,例如,苹果越狱、安卓 root,也是为了突破权限使用这些对用户隐藏的属性和行为

  • 现实事物有不公开的属性和行为,作为现实事物在程序中映射的类也支持,类中提供了私有成员的形式来支持,它们分别是私有成员变量和私有成员方法

  1. 定义私有成员变量:变量名以两个下划线(__)开头

  2. 定义私有成员方法:方法名以两个下划线(__)开头

  • 私有变量无法赋值,也无法获取值,私有方法无法直接被类对象使用
2、演示
class Phone:
    IMEI = None # 序列号
    producer = None # 厂商
    __current_volt = None # 当前电压

    def call_by_5g(self):
        print("开启 5G 通信")

    def __keep_single_core(self):
        print("让 CPU 以单核模式运行以节省电量")
  1. 使用私有成员变量
phone = Phone()

phone.__keep_single_core()
  • 输出结果
AttributeError: 'Phone' object has no attribute '__keep_single_core'
  1. 使用私有成员方法
phone = Phone()

print(phone.__current_volt)
  • 输出结果
AttributeError: 'Phone' object has no attribute '__current_volt'
3、补充
(1)补充说明
  1. 私有成员无法被类对象使用,但是可以被其它的成员使用

  2. 可以对类对象的与私有成员属性同名的属性赋值,但这是相当于又定义了一个新的变量,类内部的私有成员变量值不变

(2)演示
class Phone:
    IMEI = None # 序列号
    producer = None # 厂商
    __current_volt = 10 # 当前电压

    def call_by_5g(self):
        if self.__current_volt >= 1:
            self.__keep_single_core()
            print("开启 5G 通信")
        else:
            print("通信失败,电量不足")

    def __keep_single_core(self):
        print("让 CPU 以单核模式运行以节省电量")

    def show_current_volt(self):
        print(self.__current_volt)

phone = Phone()

phone.__current_volt = 100
print(phone.__current_volt)

phone.show_current_volt()
phone.call_by_5g()
  • 输出结果
100
10
让 CPU 以单核模式运行以节省电量
开启 5G 通信

五、继承

1、基本介绍
  • 继承就是从父类那里继承(复制)来成员变量和成员方法(不含私有成员),继承分为单继承和多继承
class 【类】(【父类】):
    【类体】
class 【类】(【父类 1】, 【父类 2】):
    【类体】
  • 注:多个父类中,如果有同名的成员,那么默认以继承顺序(从左到右)为优先级,即先继承的保留,后继承的被丢弃
2、演示
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 Phone2023(Phone, NFCReader, RemoteControl):
    face_id = True # 面部识别

    def call_by_5g(self):
        print("开启 5G 通信")

phone2023 = Phone2023()

phone2023.call_by_4g()
phone2023.call_by_5g()
phone2023.read_card()
phone2023.write_card()

print(phone2023.producer)
  • 输出结果
开启 4G 通信
开启 5G 通信
读取 NFC 卡
写入 NFC 卡
None
3、复写和使用父类成员
(1)基本介绍
  • 子类继承父类的成员属性和成员方法后,可以进行复写,一旦复写父类成员,那么类对象调用成员的时候,就会调用复写后的新成员

  • 如果需要使用被复写的父类的成员,需要特殊的调用方式

  1. 调用父类成员
【父类】.【成员变量】

【父类】.【成员方法】(self)
  1. 使用 super() 调用父类成员
super().【成员变量】

super().【成员方法】()
(2)演示
class Phone:
    IMEI = None
    producer = "MY_PHONE"

    def call_by_5g(self):
        print("开启父类的 5G 通信")

class Phone2023(Phone):
    producer = "MY_PHONE_2023"

    def call_by_5g(self):
        print("开启子类的 5G 通信")

    def run_by_father(self):
        print(super().producer)
        super().call_by_5g()

phone2023 = Phone2023()

print(phone2023.producer)
phone2023.call_by_5g()
phone2023.run_by_father()
  • 输出结果
MY_PHONE_2023
开启子类的 5G 通信
MY_PHONE
开启父类的 5G 通信

六、类型注解

1、类型注解引入
  • Python 在 3.5 版本的时候引入了类型注解,以方便静态类型检查工具、IDE 等第三方工具

  • 类型注解就是在代码中涉及数据交互的地方提供数据类型的注解(显式的说明)

  • 类型注解的主要功能就是帮助第三方 IDE 工具对代码进行类型推断,协助做代码提示,帮助开发者自身对变量进行类型注释

  • 类型注解支持变量的类型注解和函数形参列表和返回值的类型注解

2、变量的类型注解
(1)基本注解
【变量】: 【类型】
  1. 基础数据类型注解
var_1: int = 10
var_2: float = 3.1415926
var_3: bool = True
var_4: str = "Hello World"
  1. 类对象类型注解
class Student:
    name = None
    age = None

stu: Student = Student()
  1. 基础容器类型注解
my_list: list = [1, 2, 3]
my_tuple: tuple = (1, 2, 3)
my_set: set = {1, 2, 3}
my_dict: dict = {"a1": 123}
my_str: str = "Hello World"
  1. 容器类型详细注解
m_list: list[int] = [1, 2, 3]
m_tuple: tuple[str, int, bool] = ("Hello", 10, True)
m_set: set[int] = {1, 2, 3}
m_dict: dict[str, int] = {"a1", 100}
(2)注释中的注解
# type: 【类型】
class Student:
    name = None
    age = None

def func():
    return Student()

a = random.randint(1, 10) # type: int
b = json.loads('{"a1": 100}') # type: dict[str, 100]
c = func() # type: Student
(3)补充
  1. 为变量设置注解,显示的变量定义,一般无需注解,因为就算不写注解,也明确的知晓变量的类型,例如
var_1: int = 10
var_2: float = 3.1415926
var_3: bool = True
var_4: str = "Hello World"
  1. 一般,无法直接看出变量类型时会添加变量的类型注解,例如
a = random.randint(1, 10) # type: int
b = json.loads('{"a1": 100}') # type: dict[str, 100]
  1. 类型注解并不会真正的对类型做验证和判断,也就是说,类型注解仅仅是提示性的,不是决定性的,例如,如下代码不会报错
n1: int = "abc"
n2: str = 200
2、函数的类型注解
  • 函数的形参和返回值都可以添加类型注解
def 【函数】(【形参】: 【类型】, 【形参】: 【类型】)  -> 【返回值类型】:
    【函数体】
def add(x: int, y: int) -> int:
    return x + y

def addAll(data: list[int]) -> int:
    sum = 0;
    for x in data:
        sum += x
    return sum

res1: int = add(1, 2)
res2: int = addAll([1, 2, 3, 4, 5])
3、联合类型注解
(1)问题引入
  1. 如下代码的类型注解可以很容易定义
my_list1: list[int] = [1, 2, 3]
my_dict1: dict[str, int] = {"id": 10, "age": 20}
  1. 如下的代码的类型注解却不好定义
my_list2 = [1, 2, "Hello World"]
my_dict2 = {"name": "jack", "age": 20}
(2)解决方案
Union[【类型】, 【类型】]
  • 联合类型注解,在变量注解、函数的形参和返回值注解中,均可使用
my_list3: list[Union[str, int]] = [1, 2, "Hello World"]
my_dict3: dict[str, Union[str, int]] = {"name": "jack", "age": 20}

def fn(data: Union[str, int]) -> Union[str, int]:
    if type(data) == int:
        return data * 10
    if type(data) == str:
        return  data + data

print(fn(1)) # 10
print(fn("Hello")) # HelloHello

七、多态

1、基本介绍
  • 多态指的是多种状态,即完成某个行为时,使用不同的对象会得到不同的状态,例如,实现某个功能的函数,传入不同的对象,得到不同的状态

  • 多态常作用在继承关系上,例如,函数形参声明接收父类对象,实际传入父类的子类对象进行工作,即,以父类做定义声明,以子类做实际工作,用以获得同一行为,不同状态

2、演示
class Animal:
    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        print("小狗汪汪叫")

class Cat(Animal):
    def speak(self):
        print("小猫喵喵叫")

def make_speak(animal: Animal):
    animal.speak()

animal = Animal()
dog = Dog()
cat = Cat()

make_speak(animal)
make_speak(dog)
make_speak(cat)
  • 输出结果
小狗汪汪叫
小猫喵喵叫
3、抽象类
(1)基本介绍
  • 上述父类 Animal 的 speak 方法,是空实现(pass),这种设计的含义是父类用来确定有哪些方法,但具体的方法实现由子类自行决定,这种写法称之为抽象类(接口)
  1. 抽象类:含有抽象方法的类称之为抽象类

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

(2)演示
class Person:
    def eat(self):
        pass

    def work(self):
        pass

class Teacher(Person):
    def eat(self):
        print("老师去教室食堂用餐")

    def work(self):
        print("老师开始教书")

class Worker(Person):
    def eat(self):
        print("工人去工地食堂用餐")

    def work(self):
        print("工人开始劳作")

teacher = Teacher()
worker = Worker()

teacher.eat()
teacher.work()

worker.eat()
teacher.work()
  • 输出结果
老师去教室食堂用餐
老师开始教书
工人去工地食堂用餐
老师开始教书

标签:__,10,name,Python,self,多态,print,age,def
From: https://blog.csdn.net/weixin_52173250/article/details/142914972

相关文章

  • 人工智能第五次课程 10月14日
    通过提问同学见习是否有备课过程,了解同学们现有的备课工具与手段。引出本课程主题:该如何快速高效做出教案。介绍人工智能是计算机科学的一个分支,致力于创造模仿人类智能行为的机器或系统。这与教育学中的“智能”概念相似,但范围更广。从教育者的角度来理解AI,规则基础系统转而为......
  • 人工智能教育技术学 第五次课程 2024年10月14日
    导课:教师课前备方法和工具分享学习如何快速备课AI是计算机科学的一个分支,致力于致力于创造能够模仿人类智能行为的机器或系统。这与教育学中的"智能"概念有些相似,但范围更广,包括感知、学习、推理、问题解决等能力。从教育者角度理解AI:1.规则基础系统——机械学习——深......
  • 基于yolov10的PCB板缺陷检测系统,支持图像、视频和摄像实时检测【pytorch框架、python
    更多目标检测和图像分类识别项目可看我主页其他文章功能演示:yolov10,PCB板缺陷检测系统,支持图像、视频和摄像实时检测【pytorch框架、python】_哔哩哔哩_bilibili(一)简介基于yolov10的PCB板缺陷检测系统是在pytorch框架下实现的,这是一个完整的项目,包括代码,数据集,训练好的模型......
  • python中global关键字的作用
    python中global关键字的作用python中初始化一个变量y_axis_RA=[]一个函数中给y_axis_RA赋值,但是该变量显示未使用,在另外一个函数中使用y_axis_RA提示变量为空在Python中,变量作用域的问题可能会导致你遇到的情况。如果你在函数外部初始化了一个变量y_axis_RA=[],然后在函数......
  • 基于python+flask框架的影片个性化推荐系统(开题+程序+论文) 计算机毕设
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着信息技术的飞速发展和互联网的广泛应用,影视娱乐已成为人们日常生活中不可或缺的一部分。在海量影片资源面前,用户往往难以快速找到符合......
  • 基于python+flask框架的游泳馆会员管理系统(开题+程序+论文) 计算机毕设
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着现代生活水平的提高,人们越来越注重身体健康与休闲娱乐的结合,游泳馆作为重要的健身场所,其管理效率与服务质量直接关系到顾客满意度与经......
  • 基于python+flask框架的在线诊疗健康管理系统(开题+程序+论文) 计算机毕设
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着互联网技术的飞速发展,医疗行业正逐步向数字化、智能化转型。传统的诊疗模式受限于地域、时间等因素,难以满足广大患者日益增长的医疗需......
  • 校园网python认证
    认证采用的是get的方式,参数大家可以根据自己校园网情况更改。importrequestsimportsocketimportjsonimportosdefget_local_ip():try:withsocket.socket(socket.AF_INET,socket.SOCK_DGRAM)ass:s.connect(("8.8.8.8",80))#连接到......
  • Python决策树算法:面向对象的实现与案例详解
    目录Python决策树算法:面向对象的实现与案例详解引言一、决策树算法概述1.1决策树的基本思想1.2分类与回归树1.3决策树的构建过程1.4决策树的优缺点优点缺点二、面向对象的决策树实现2.1类的设计2.2Python代码实现2.3代码详解三、案例分析3.1案例一:鸢尾花分类......
  • Dynamsoft Barcode Reader SDK Java 10.4.2000
    ImprovingVendorManagementEfficiencywithOCRandDocumentProcessingEffectivevendormanagementintoday’sdynamicbusinesslandscapeofteninvolveshandlinglargevolumesofphysicaldocuments,whichposesasignificantchallenge.Extractingkeydeta......