Python面向对象

一、初识对象

使用对象组织数据。在程序中可以做到和生活中一样,设计表格、生产表格、填写表格的组织形式的。
1.在程序中设计表格:--设计类
class Studen:
    name = None #记录学生姓名
2.在程序中打印生产表格:--创建对象
# 基于类创建对象
stu_1 = Student()
stu_2 = Student()
3. 在程序中填写表格:--对象属性赋值
stu_1.name = "张三" # 为对象赋予name属性
stu_2.name = "张四"
"""
演示类的创建
"""
# 1.设计一个学生类 :类比生活中设计一张记录学生信息的登记表
class Student:
    name = None
    gender = None
    nationality = None
    native_place = None
    age = None
# 2.创建一个对象(类比生活中打印一张登记表)
stu_1 = Student()
stu_2 = Student()
# 3.对象属性进行赋值(类比生活中:填写表单)
stu_1.name = "张三"
stu_1.gender = '男'
stu_1.nationality = "中国"
stu_1.native_place = "山东省"
stu_1.age = "23"
# 4.获取对象中记录的信息
print(stu_1.name)
print(stu_1.gender)
print(stu_1.nationality)
print(stu_1.native_place)
print(stu_1.age)

二、成员方法

1、类的定义和使用语法:
  • class是关键字,表示要定义类了
  • 类的属性,即定义在类中的变量(成员变量) 
  • 类的行为,即定义在类中的函数(成员方法)
语法:
class  类名称:
    类的属性
    
    类的行为
创建类对象的语法: 对象 = 类名称()
2、成员变量和成员方法的使用:
什么是类的行为(方法)?
可以看出  类中可以:
  • 定义属性用来记录数据
  • 定义函数用来记录行为
其中:
  • 类中定义的属性(变量)称作-- 成员变量
  • 类中定义的行为(函数)称作-- 成员方法
在类中定义成员方法和定义函数基本一致,但仍有细微区别:
可以看到,在方法定义的参数列表中,有一个:self关键字
self关键字是成员方法定义的时候,必须填写的。
· 它用来表示类对象自身的意思 
· 当我们使用类对象调用方法的是,self会自动被python传入
·  在方法内部,想要访问类的成员变量,必须使用self
3、self关键字
self --尽管在参数列表中,但是传参的时候可以忽略它
"""
演示面向对象类中的成员方法定义和使用
"""
# 定义一个带有成员方法的类
class Student:
    name = None


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


    def say_hi2(self,msg):
        print(f"大家好,我是{self.name},{msg}")
stu_1 = Student()
stu_1.name = "李四"
stu_1.say_hi2("哎哟不错呀")


stu_2 = Student()
stu_2.name = "李wy"
stu_2.say_hi()

三、类和对象

现实世界的事物也有属性和行为,类也有属性和行为;
实用程序中的类,可以完美的描述现实世界的事物。那么为什么要创建对象才能使用呢?
类只是一种程序内的“设计图纸”,需要基于图纸生产实体(对象),才能正常工作 。这种思想就称之为: 面向对象编程
使用类和对象描述现实事物
在程序中通过类来描述;
基于类创建对象
这就是面向对象编程: --设计类,基于类创建对象,由对象做具体的工作。

四、构造方法 

1、属性(成员变量)的赋值
2、 构造方法:
Python类可以使用__init__()方法,称之为构造方法
可以实现:--在创建类对象(构造类的时候)
  • 自动执行
  • 将参数自动传递给__init__方法使用 
3、构造方法注意事项
  • 重要的事情说三遍,构造方法名称:__init__   __init__   __init__ , 千万不要忘记init前后都有2个下划线 
  • 构造方法也是成员方法,不要忘记在参数列表中提供:self  
  • 在构造方法内定义成员变量,需要使用self关键字 
这是因为:变量是定义在构造方法内部,如果要成为成员变量,需要用self来表示。
4、构造方法案例:
"""
设计一个类,记录学生的:
姓名、年龄、地址,这3类信息
通过for循环,配合input输入语句,并使用构造方法,完成学生信息的键盘录入
输入完成后,使用print语句,完成信息的输出
"""
class Student:
    name = None
    age = None
    addres = None


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




for x in range(1,10):
    name_in = input("请输入学生姓名:")
    age_in = input("请输入学生年龄:")
    address_in = input("请输入学生地址:")
    stu = Student(name_in,age_in,address_in)
    print(f"当前录入第{x}位学生信息,总共需要录入10位学生信息")
    print(f"学生{x}信息录入完成,信息为:【学生姓名:{stu.name},年龄:{stu.age},地址:{stu.addres}】")


print("所有学生的信息录入完毕")

五、其他内置方法 --魔术方法

目录

1、__str__ 字符串方法
2、__lt__ 小于符号比较方法 
直接对2个对象进行比较是不可以的,但是在类中实现__lt__方法,即可同时完成: 小于符号 和 大于符号 2种比较
方法名:__lt__
传入参数:other,另一个类对象 
返回值:True 或 False 
内容:自行定义
3、__le__ 小于等于比较符号方法
魔术方法:__le__可用于:<=、>=两种比较运算符上。
4、__eq__,比较运算符实现方法
  • 不实现__eq__方法, 对象之间可以比较,但是是比较 内存地址,也即是:不同对象==比较一定是False结果。 
  • 实现了__eq__方法,就可以按照自己的想法来决定2个对象是否相等了。
"""
演示Python内置的各类魔术方法
"""
class Student:
    def __init__(self,name,age):
        self.name = name
        self.age = age


    # __str__ 控制类对象转变为字符串
    def __str__(self):
        return f"{self.name},{self.age}"


    # __lt__ 小于符号比较方法--实现小于符号 和 大于符号 2种比较
    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("自制力",32)
stu2 = Student("养成",21)
print(stu1)      # 输出:自制力,32
print(str(stu1)) # 输出:自制力,32
print(stu1.age > stu2.age) #输出True
print(stu1.age < stu2.age)  #输出False
print(stu1.age <= stu2.age) #输出False
print(stu1.age >= stu2.age) #输出True
print(stu1.age == stu2.age) #输出False

六、面向对象编程特性

面向对象编程 是 许多编程语言都支持的一种编程思想;简单理解是:基于模板(类)去创建实体(对象),使用对象完成功能开发
面向对象的三大特性:
  • 封装
  • 继承
  • 多态
1、封装
· 对用户隐藏的属性和行为:
现实世界中的事物,有属性和行为。但是不代表所有的属性和行为都是开放给用户使用的
· 私有成员  
类中提供了私有成员的形式来支持不公开的属性和行为
  • 私有成员变量
  • 私有成员方法
定义私有成员的方式:
  • 私有成员变量:变量名以__开头(2个下划线)
  • 私有成员方法:方法名以__开头(2个下划线) 即可完成私有成员的设置
使用私有成员:
私有成员无法被类对象使用,但是可以被其他成员的成员使用。简而言之,私有的可以被内部使用,但是不能被外部创建的类对象使用。
"""
演示面向对象封装思想中私有成员的使用
"""
class Phone:
    __cunrent_voltage = 0.3  # 当前手机运行电压 私有


    def __keep_single_core(self):  # 私有方法
        print("让CPU以单核模式运行")


    def call_by_5g(self):
        if self.__cunrent_voltage >= 1:
            print("5g通话已开启")
        else:
            self.__keep_single_core()
            print("电量不足,无法使用5G通话,并已设置为单核模式。")


phone = Phone()
phone.call_by_5g()

#输出:
让CPU以单核模式运行
电量不足,无法使用5G通话,并已设置为单核模式。
私有成员的实际意义:
在类中提供仅供内部使用的属性和方法
而不对外开放(类对象无法使用)
案例:设计一个手机类,内部包含:私有成员变量:__is_5g_enable,类型bool,True表示开启5g,False表示关闭5g 私有成员方法:__check_5g(),会判断私有成员__is_5g_enable的值 若为True,打印输出:5g开启 若为False,打印输出:5g关闭,使用4g网络 公开成员方法:call_by_5g(),调用它会执行 调用私有成员方法:__check_5g(),判断5g网络状态 打印输出:正在通话中
"""
设计一个手机类,内部包含:
私有成员变量:__is_5g_enable,类型bool,True表示开启5g,False表示关闭5g
私有成员方法:__check_5g(),会判断私有成员__is_5g_enable的值
若为True,打印输出:5g开启
若为False,打印输出:5g关闭,使用4g网络
公开成员方法:call_by_5g(),调用它会执行
调用私有成员方法:__check_5g(),判断5g网络状态
打印输出:正在通话中
"""
class Phone:
    __is_5g_enable = False


    def __check_5g(self):
        if self.__is_5g_enable == True:
            print("5g开启")
        else:
            print("5g关闭,使用4g网络")


    def call_by_5g(self):
        self.__check_5g()
        print("正在通话中")


phone = Phone()
phone.call_by_5g()

通过这个案例,可以概括:私有成员有什么意义? --可以直接去定义不直接对用户开放的属性和行为。
2、继承:
继承的概念引出
对于phone更新迭代,设计师肯定会选择基于老款的设计图,修修改改。
即新的设计图本质上继承了老设计图思路再进行修改
如何基于老的类来进行升级修改?  --使用继承来实现
继承分为 单继承和多继承
继承表示从父类那里继承(复制)成员变量和成员方法  不含私有
class 类名(父类名):
    类内容体
· 单继承:
"""
演示面向对象--继承--单继承基础语法
"""
# 父类
class Phone:
    IMEI = None     # 序列号
    producer = "SP" #厂商


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


# 单继承
class Phone2022(Phone):
    faceID = "10001"   #面部识别


    def call_by_5g(self):
        print("2022年新功能:5G通话")


phone = Phone2022()
print(phone.producer)
phone.call_by_4g()
phone.call_by_5g()
输出:
SP
4g通话
2022年新功能:5G通话

· 多继承 
Python之间也支持多继承,即一个类,可以继承多个父类
多个父类中,如果有同名的成员,那么默认以继承顺序(从左到右)为优先级。即:先继承的保留,后继承的被覆盖
"""
演示面向对象--多继承
注意:对于父类中同名的成员(成员属性和成员方法)访问时,按照左边的先来 谁先继承谁的优先级高
"""
class Phone:
    IMEI = None     # 序列号
    producer = "SP" #厂商
    __store = 512


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


class NFCReader:
    NFC_type = "第五代"
    producer = "SPbear"


    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  # 作用是不产生语法错误 pass是占位语句,用来保证函数(方法)或类定义的完整性,表示无内容,空的意思


phone = myPhone()
phone.call_by_4g()
phone.read_card()
phone.write_card()
phone.control()
print(phone.producer)  

输出:
4g通话
NFC读卡
NFC写卡
红外遥控开启了
SP

· 复写和使用父类方法:
(1)复写:子类继承父类的成员属性和成员方法后,如果对其“不满意”,那么可以进行复写。即:在子类中重新定义同名的属性或方法。
(2)调用父类同名成员
一旦复写父类成员,那么对象调用成员的时候,就会调用复写后的新成员;如果需要使用被复写的父类的成员,需要特殊的调用方式:
只能在 子类内调用父类的同名成员 。子类的类对象直接调用会调用子类复写的成员
"""
面向对象继承--复写使用父类成员
"""
# 父类
class Phone:
    IMEI = "20221210"
    producer = "SP"


    def call_by_5g(self):
        print("5g通话模式")


# 定义子类 复写父类
class myPhone(Phone):
    producer = "SPplus"


    def call_by_5g(self):
        print("开启CPU单核模式,保持通话省电")
        # # 方式1 通过父类名调用父类里面的成员
        # print(f"父类的厂商:{Phone.producer}")
        # Phone.call_by_5g(self)    # 调用父类的成员方法 括号内一定要加self
        # 方式2 利用super
        print(f"父类的厂商:{super().producer}")
        super().call_by_5g()
        print("关闭CPU单核模式,确保性能")


phone = myPhone()
phone.call_by_5g()
print(phone.producer,phone.IMEI)
输出:
开启CPU单核模式,保持通话省电
父类的厂商:SP
5g通话模式
关闭CPU单核模式,确保性能
SPplus 20221210

3、类型注解
Python在3.5版本的时候引入了类型注解,以方便静态类型检查工具,IDE等第三方工具。类型注解:在代码中涉及数据交互的地方,提供数据类型的注解(显式的说明)。 
  主要功能: 
  • 帮助第三方IDE工具(如PyCharm)对代码进行类型推断,协助做代码提示 
  • 帮助开发者自身对变量进行类型注释 
  支持: 
  • 变量的类型注解 
  • 函数(方法)形参列表和返回值的类型注解- 
· 类型注解的语法
(1)为变量设置类型注解 --基础语法:
  变量:类型
(2)对注释进行类型注解  语法:type: 类型
(3)类型注解的限制
类型注解主要功能在于:
· 帮助第三方IDE工具(如PyCharm)对代码进行类型推断,协助做代码提示 
· 帮助开发者自身对变量进行类型注释(备注)  
并不会真正的对类型做验证和判断。 
也就是,类型注解仅仅是提示性的,不是决定性的 不会报错的哦。
(4)函数和方法的类型注解 形参注解/返回值注解
形参注解语法:
返回值注解语法:
(5)Union联合类型注解
使用Union[类型, ......, 类型]  可以定义 联合类型注解
Union联合类型注解,在 变量注解、函数(方法)形参和返回值注解中,均可使用。
4、多态 
· 多态:多种状态,即完成某个行为时,使用不用的对象 会得到不同的状态
同样的行为(函数),传入不同的对象,得到不同的结果
· 抽象类(接口) 
提出标准后,不同的厂家各自实现标准的要求
抽象类的作用:
可以用于做顶层的设计( 设计标准),以便子类做具体实现
也是对子类的一种软性约束要求子类必须复写(实现)父类的一些方法,配合多态使用获得不同的工作状态。
七、综合案例 --数据分析
案例需求:某公司,有2份数据文件,现需要对其进行分析处理,计算每日的销售额并以柱状图表的形式进行展示。
需求分析
1、 使用面向对象思想完成数据读取和处理
· 1月份数据是普通文本,使用逗号分割数据记录,从前到后分别是(日期,订单id,销售额,销售省份)
· 2月份数据是JSON数据,同样包含(日期,订单id,销售额,销售省份)
2、 基于面向对象思想重新认知第三方库使用(PyEcharts)
实现步骤:
1、设计一个类可以完成数据的封装
2、设计一个抽象类 定义文件读取的相关功能,并使用子类实现具体功能
3、读取文件生产数据对象
4、进行数据需求的逻辑计算(计算每一天的销售额)
5、通过pyecharts进行图形绘制
代码和数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值