python小白学习笔记(06)

目录

四十、类

        1、定义:

        2、语法:

        3、思考

        4、__init__()方法

        5、魔术方法

        ①、__init__()方法

        ②、__str__字符串方法

        ③、__lt__小于符号比较方法

        ④、__eq__比较运算符实现方法

        ⑤、__le__小于等于比较符号方法

        ⑥、小结

        6、封装

        ①、概念

        ②、私有成员、私有变量

        ③、如何定义:

        ④、访问限制:

        7、继承

        ①、定义:

        ②、语法:

        ③、pass关键字

        8、复写

        9、类型注解

        ①、变量类型注解

        ②、方法类型注解

        ③、Union类型

        10、多态


四十、类

        1、定义:

        在程序中是可以做到和生活中那样,设计表格,生产表格,填写表格的组织形式的。

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

class student:
    name = None    #记录学生姓名

        在程序中打印生产表格,我们称之为:创建对象

# 基于类创建对象
stu1 = student()
stu2 = student()

        在程序中填写表格,我们称之为:对象属性赋值

stu1.name = 'ikun'      # 为学生1对象赋予属性值
stu2.name = 'geigei'    # 为学生2对象赋予属性值

        2、语法:

        在上述中,我们简单了解到可以使用类去封装属性,并基于类创建出一个个的对象来使用。

        现在我们来看看类的使用语法:

        class 类名称:               #class是关键字,表示要定义类了

                类的属性                #类的属性,即定义在类中的变量(成员变量)

                类的行为                #类的行为,即定义在类中的函数(成员方法)

        创建类对象的语法:

        对象 = 类名称()

        成员方法的定义语法:

        在类中定义成员方法和定义函数基本一致,但还是有细微区别:

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

                方法体

        注意:在定义方法中self关键字是必须要填写的

                   当我们使用类对象调用方法的时,self会自动被python传入

                   在方法内部,想要访问类的成员变量,必须使用self

        self关键字

        尽管在参数列表中,但是传参的时候可以忽略它, 如:

class student:
    name = None    # 记录学生姓名
    def say_hi(self, msg):
        print(msg)
    def say_name(self):
        print(self.name)
# 基于类创建对象
stu1 = student()
stu1.name = 'ikun'      # 为学生1对象赋予属性值
stu1.say_hi('hi')       #调用的时候需要传入msg参数
stu1.say_name()         #调用的时候无需传参

        注意:定义方法的时候需要self关键字,在调用类的属性的时候也需要self关键字,传参则不用

        3、思考

        类和对象的关系?

                类是程序的”设计图纸“;对象是基于图纸生产的具体实例

        什么是面向对象编程?

                面向对象编程就是,使用对象进行编程。即,设计类,基于类创建对象,并使用对象来完成具体的工作        

        4、__init__()方法

        python类可以使用:__init__()方法,称之为构造方法

        作用:

                在创建类对象(构造类)的时候,会自动执行

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

class student:
    name = None    # 记录学生姓名
    age = None     # 记录学生年龄
    def __init__(self, name, age):
        self.name = name
        self.age = age
        print("创建了一个对象")
# 基于类创建对象
stu = student('ikun',2.5) # 输出:创建了一个对象
print(stu.name)                     # 输出:ikun
print(stu.age)                      # 输出:2.5

        注意:

                构建类时传入的参数会自动提供给__init__方法

                构建类的时候__init__方法会自动执行

                构造方法名称init前后都有2个下划线,同时不要忘记了self        

                同时在__init__方法内部使用过的变量,可以不需要在外部定义如:

class student:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        print("创建了一个对象")
# 基于类创建对象
stu = student('ikun',2.5) # 输出:创建了一个对象
print(stu.name)                     # 输出:ikun
print(stu.age)                      # 输出:2.5

        5、魔术方法

        上面学习的__init__()方法是python内置的方法之一

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

        ①、__init__()方法

                上述已经介绍,不做过多赘述

        ②、__str__字符串方法

                当我们需要将类对象转换为字符串之时,不写str函数会直接输出内存地址,如:

class student:
    def __init__(self, name, age):
        self.name = name
        self.age = age
# 基于类创建对象
stu = student('ikun',2.5) # 输出:创建了一个对象
print(stu)          # 输出:<__main__.student object at 0x000002A9F0C64230>
print(str(stu))     # 输出:<__main__.student object at 0x000002A9F0C64230>

                内存地址没用多大作用,这时我们可以通过__str__方法,控制类转换为字符串的行为。

class student:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def __str__(self):
        return f'{self.name} is {self.age}'
# 基于类创建对象
stu = student('ikun',2.5) # 输出:创建了一个对象
print(stu)          # 输出:ikun is 2.5
print(str(stu))     # 输出:ikun is 2.5
        ③、__lt__小于符号比较方法

        直接对2个对象进行比较是不可以的,但是在类中实现__lt__方法,既可同时完成:小于符号和大于符号2种比较

class student:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def __lt__(self, other):
        return self.age < other.age
# 基于类创建对象
stu = student('ikun',2.5) # 输出:创建了一个对象
stu1 = student('geigei',25) # 输出:创建了一个对象
print(stu < stu1) # 结果:True
print(stu > stu1) # 结果:False

        其中的other是另外一个类对象,返回值为布尔类型,内容可以根据需要自行定义

        ④、__eq__比较运算符实现方法

        不实现__eq__方法,对象之间是可以比较的,比较的是内存地址并没实际意义,不同对象比较的结果一定是False结果,实现后则可以根据需要自行决定了

class student:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def __eq__(self, other):
        return self.age == other.age
# 基于类创建对象
stu = student('ikun',2.5) # 输出:创建了一个对象
stu1 = student('geigei',25) # 输出:创建了一个对象
print(stu == stu1) # 结果:False

           其中的other是另外一个类对象,返回值为布尔类型,内容可以根据需要自行定义

        ⑤、__le__小于等于比较符号方法

            现实生活中,我们还有可能需要用到<=或者>=的比较运算符,那是不是运用__eq__方法和__le__方法就可以实现了呢,答案肯定是不可能的,你如果这么写了,程序会给你一个报错,说它不认识<=或>=符合,这个时候就要用到我们的__le__方法了

class student:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def __le__(self, other):
        return self.age <= other.age
# 基于类创建对象
stu = student('ikun',2.5) # 输出:创建了一个对象
stu1 = student('geigei',25) # 输出:创建了一个对象
print(stu <= stu1) # 结果:True
print(stu >= stu1) # 结果:False

        其中的other是另外一个类对象,返回值为布尔类型,内容可以根据需要自行定义

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

        6、封装

        ①、概念

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

        ②、私有成员、私有变量

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

        ③、如何定义:

                成员变量和成员方法的命名均以__作为开头即可(2个下划线)

        ④、访问限制:

                类对象无法访问私有成员,但是可以通过类中其他成员间接的访问私有成员

        7、继承

        ①、定义:

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

        ②、语法:

class 类(父类[,父类2,......,父类N]):

        类内容体

                子类构建的类对象可以有自己的变量和方法,也可以直接使用父类的变量和方法(不包含私有方法和私有变量)

                注意:单继承就是一个类继承另外一个类,多继承就是一个类继承多个类,按照顺序从左向右依次继承,而在多继承中,如果父类有同名方法或者属性,先继承的优先级高(左边的高)

        ③、pass关键字

        在子类中继承的变量和方法已经够用时,无需添加新内容时,为了编译能不报错,需要使用pass关键字,其表示无内容,空的意思

        8、复写

        子类继承父类的成员属性和成员办法后,如果对其“不满意”,那么可以进行复写。

        即:在子类中重新定义同名的属性或方法即可

class ji:
    IMEI = None         # 序列号
    producer = "ikun"   # 厂商
    
    def call_by_egg(self):
        print("geigei")
        
class iji(ji):
    producer = "IT"             # 复写父类属性
    
    def call_by_egg(self):      # 复写父类方法
        print("geigei的蛋")

        一旦复写父类成员,那么类对象调用成员的时候,就会调用复写后的新成员

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

        方式1:

        调用父类成员

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

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

        方式2:

        使用super()调用父类成员

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

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

class ji:
    IMEI = None         # 序列号
    producer = "ikun"   # 厂商

    def call_by_egg(self):
        print("geigei")
        return None

class iji(ji):
    producer = "IT"             # 复写父类属性

    def call_by_egg(self):      # 复写父类方法
        # 方式1调用父类成员
        ji.call_by_egg(self)
        # 方式2调用父类成员
        super().call_by_egg()
        return None

j = iji()
j.call_by_egg() # 输出俩个geigei

        注意:只可以在子类内部调用父类的同名成员


        9、类型注解

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

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

        主要功能:

                帮助第三方IDE工具(如PyCharm)对代码进行类型推断,协助做代码提示

                帮助开发者自身对变量进行类型注释

                并不会真正的对类型做验证和判断

                也就是,类型注解仅仅是提示性的,不是决定性的

                据类型和注解类型无法对应也不会导致错误

        支持:

                变量的类型注解

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

        ①、变量类型注解

                基础语法1:变量:类型

# 基础数据类型注解
var1: int = 10
var2: float = 2.5
var3: bool = True
var4: str = "ikun"
# 类对象类型注解
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 = {"ikun": 2.5}
my_str: str = 'ikun'
# 容器类型详细注解
my_list1: list[int] = [1, 2, 3]
my_tuple1: tuple[str, int, bool] = ('ikun', 2, True)
my_set1: set[int] = {1, 2, 3}
my_dict1: dict[str, float] = {'ikun': 2.5}

        注意:元组类型设置类型详细注解,需要将每一个元素都标记出来

                字典类型设置详细注解,需要2个类型,第一个是key第二个是value

                基础语法2:#type:类型

# 除了使用变量:类型,这种语法做注解外,也可以在解释中进行类型注解。
import json
from random import random
from _ctypes_test import func
class student:
    pass
var1 = random.randint(1,10)  # type:int
var2 = json.loads(data)      # type:dict[str,int]
var3 = func()                # type:student

        为变量设置注解,显示的变量定义,一般无需注解,无法直接看出来变量类型之时会添加变量的类型注解

        ②、方法类型注解

        形参注解:

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

                pass

def test(x:int,y:int):
    return x+y

        返回值注解:

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

                pass

def test(x:int,y:int) -> int:
    return x+y
        ③、Union类型

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

        语法:

        导包:from typing import Union

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

        union联合类型注解,在变量注解、函数(方法)形参和返回值注解中,据可以使用

from typing import Union
my_list: list[Union[int, str]] = [1, 2, 'hello', 'world']
my_dict: dict[str,Union[int, str]] = {'name': 'ikun', 'age': 23}

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

        10、多态

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

# 定义父类
class animal:
    def speak(self):
        pass
#子类继承
class dog(animal):
    def speak(self):
        print("汪汪汪")
#子类继承
class cat(animal):
    def speak(self):
        print("喵喵喵")
def main(animal):
    animal.speak()
dog = dog()
cat = cat()
main(dog)
main(cat)

        父类animal的speak方法是空实现,这种设计的含义是:父类用来确定由哪些方法

        具体的方法实现,由子类自行决定,这种写法叫抽象类(也可叫接口)

        一般是由组长决定执行的内容,然后组员去实现具体的内容

        父类做定义声明,子类做实际工作,用以获得同一行为,不同状态

  • 21
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逍 朽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值