Python零基础入门学习笔记(三)

Python 基础入门学习

五.面向对象

  1. 是对一系列具有相同特征和行为的事物的统称,是一个抽象的概念,不是真实存在的事物。对象是由类创建出来的真实存在的事物。

    #创建类
    class 类名():  #类名要满足标识符命名规则,同时遵循大驼峰命名习惯
        代码
        ......
    	def 函数名(self):  #self指调用该函数的对象
            代码
    
    #创建对象
    对象名 = 类名()
    
  2. 类外面添加对象属性

    对象名.属性名 =

    类外面获取对象属性

    对象名.属性名
    

    类里面获取对象属性

    self.属性名
    

    综合实例

    class Washer():
        def wash(self):
            print('wash the clothes!')
        def get_size(self):
            print(f'此洗衣机的尺寸是{self.width} X {self.height}')
    
    haier1 = Washer()
    haier1.width = 500
    haier1.height = 300
    
    haier2 = Washer()
    haier2.width = 600
    haier2.height = 400
    
    print(haier1.width)
    haier1.get_size()
    haier2.get_size()
    
  3. 魔法方法: __init__() 、 __str__()、__del__()。

    #1. __init__() 初始化对象。
    #创建对象时默认被调用;不需开发者传递self参数,python解释器会自动把当前对象引用传递过去。
    
    class washer():
        def __init__(self,width,height):
            self.width = width
            self.height = height
    
        def print_info(self):
            print(f'{self.width} X {self.height}')
    
    h = washer(500,800)
    h.print_info()
    #输出结果 500 X 800
    
    #2. __str__() 使得用print输出对象时,输出该方法中return的数据,而不再输出对象的内存地址。
    
        def __str__(self):
            return "这是洗衣机对象!"
        
    print(h)
    #输出结果 这是洗衣机对象!
    
    #3. __del__() 当删除对象时,python解释器会默认调用__del__()方法
    
        def __del__(self):
            print(f'{self}对象已经被删除!')
         
    del h
    #输出结果 <__main__.washer object at 0x000002531DF744F0>对象已经被删除!
    
  4. 两个案例

    烤地瓜

    #需求:1.被烤时间和地瓜状态相对应  2.用户可按意愿添加调料
    
    class SweetPotato():
    
        def __init__(self):
            self.cook_time=0
            self.cook_state='生的'
            self.condiments=[]
    
        def cook(self, time):
            if time >=0:
                self.cook_time += time
                if 0<= self.cook_time < 3:
                    self.cook_state = '生的'
                elif 3 <= self.cook_time < 5:
                    self.cook_state = '半生不熟'
                elif 5 <= self.cook_time < 8:
                    self.cook_state = '熟了'
                elif self.cook_time >= 8:
                    self.cook_state = '糊了!'
            else:
                print('时间刺客?!')
    
        def add_condiment(self, con):
            self.condiments.append(con)
    
        def __str__(self):
            return f'这个地瓜烤了{self.cook_time}分钟,状态是{self.cook_state},添加的调料有{self.condiments}'
    
    p = SweetPotato()
    p.add_condiment('番茄酱')
    print(p)
    p.cook(8)
    p.add_condiment('芥末')
    print(p)
    
    # 这个地瓜烤了0分钟,状态是生的,添加的调料有['番茄酱']
    # 这个地瓜烤了8分钟,状态是糊了!,添加的调料有['番茄酱', '芥末']
    

    搬家具

    #需求 将小于房子剩余面积的家具摆放到房子中
    
    class Furniture():
        def __init__(self,name,area):
            self.name = name
            self.area = area
    
    class House():
        def __init__(self,adress,area):
            self.adress = adress
            self.area = area
            self.free_area = area
            self.furniture = []
    
        def add_furniture(self,item):
            if self.free_area >= item.area:
                self.furniture.append(item.name)
                self.free_area -= item.area
            else:
                print('家具太大,剩余面积不足,无法容纳')
    
        def __str__(self):
            return f'这个房子的地址是{self.adress},总面积是{self.area},当前剩余面积是{self.free_area},家具有{self.furniture}'
    
    bed = Furniture('双人床',6)
    sofa = Furniture('沙发',10)
    court = Furniture('高尔夫球场',1000)
    house = House('陆家嘴',200)
    print(house)
    house.add_furniture(bed)
    house.add_furniture(sofa)
    house.add_furniture(court)
    print(house)
    
    #这个房子的地址是陆家嘴,总面积是200,当前剩余面积是200,家具有[]
    #家具太大,剩余面积不足,无法容纳
    #这个房子的地址是陆家嘴,总面积是200,当前剩余面积是184,家具有['双人床', '沙发']
    
  5. 继承: Python面向对象的继承指的是多个类之间的所属关系,即子类默认继承父类的所有属性和方法,具体如下:

    #定义父类A
    class A(object):
        def __init__(self):
            self.num = 1
            
        def infor_print(self):
            print(self.num)
            
    #定义子类B,继承父类A
    class B(A):
        pass
    
    #创建对象,验证对象继承
    result = B()
    result.info_print()
    

    在python中,所有类默认继承object类,object类是顶级类或基类;其他子类叫派生类

    拓展:python2中的经典类 和 python3中的新式类

    #经典类(不由任意内置类型派生出的类)
    class 类名:
        代码
        ......
        
    #新式类
    class 类名(object):
        代码
        ......
        
    #在今后的学习和运用中,统一使用新式类
    

    单继承:一个子类继承一个父类,这种单一的继承关系称为单继承。

    多继承:一个子类同时继承多个父类。

    class 子类(父类A,父类B,父类C)
    #当两个父类中的属性和方法有同名时,优先继承第一个父类中的同名属性和方法,即继承A类。
    

    子类重写父类同名属性与方法:在子类中可以重写与父类中同名的属性和方法。子类创建的对象调用属性和方法时,会调用子类中重写的属性和方法。

    拓展: **__mro__**顺序 方法查看类的继承层级顺序。

    print(类名.__mro__)
    

    子类调用父类同名属性和方法:在子类中重写了父类中同名属性与方法的情况下,调用父类中的同名属性和方法。

    class 子类B(父类A):
        def 同名方法(self):
            #如果之前调用了父类的属性和方法,则父类属性会覆盖子类属性,故在调用子类属性前,先调用子类自己的初始化
            self.__init__(self)
            代码
            
        def 调用父类方法(self):
            #调用父类方法,为保证调用到的属性也是父类的属性,必须在调用方法前调用父类的初始化
            父类A.__init__(self)
    		父类A.同名方法(self)
    

    多层继承:一般指大于两层的继承关系。

    class A(object):
    	...
        
    class B(A):
        ...
        
    class C(B):  #多层继承
        ...
    

    super()调用父类方法:自动查找父类,直接调用父类的属性方法,调用顺序遵循__mro__类属性的顺序。

    class A(object)
    class B(A)
    
    class C(B):
        #方法一:原始方法
        def useAB(self):
            A.__init__(self)
            A.同名方法(self)
            B.__init__(self)
            b.同名方法(self)
            
        #方法二:super()方法
        #方法2.1 super(当前类名,self).函数()
        def useAB(self):
            super(C,self).__init__()
            super(C,self).同名方法() 
            #此时会调用父类B的方法;若想调用A类的方法,需要在B类的同名方法中添加同样的super方法代码来调用A类
            
        #方法2.2 super().函数()
        def useAB(self):
            super().__init__(self)
            super().同名方法()
            #同样调用父类B的方法;无法直接调用父类的父类A的属性和方法
    
  6. 私有权限

    设置私有属性和方法:在属性名和方法名前面加上两个下划线。

    私有属性和私有方法只能在类内访问和修改,即子类无法继承或直接访问父类的私有属性和方法。

    class A(object):
        def __init__(self):
            self.name = 'A'
            self.__money = 99999  #私有属性
        
        def __CostMoney(self,money):  #私有方法
            self.__money -= money
    

    获取和修改私有属性值:可在类内定义公有函数来获取和修改 私有属性值,在类外调用该函数来实现获取和修改私有属性功能。

    #一般在类内用函数名get_xx来获取私有属性,用set_xx来修改私有属性
    class A(object):
        def __init__(self):
            self.__money = 99999
            
        def get_money(self):
            return self.__money
        
        def set_money(self,new_money):
            self.__money = new_money
            
    class B(A):
        pass
    
    b = B()
    
    b.get_money()  #成功获取父类中的私有属性
    b.set_money(0)  #成功修改父类中的私有属性
    
  7. 多态:一种使用对象的方式,子类重写父类方法,调用不同子类对象的相同父类方法,可以产生不同的执行结果。即传入不同的对象,产生不同的结果。

  8. 类属性和实例属性:类属性即类所拥有的属性,它为该类所有对象共有。类属性可以用 类对象实例对象 访问。

    类属性只能通过类对象修改

    #修改类属性
    类名.属性 =
  9. 类方法:需要用装饰器 @classmethod 来标识其为类方法,类方法第一个参数必须是类对象,一般以 cls 作为第一个参数。

    class A(object):
        __num = 777
        
        @classmethod
        def get_num(cls):
            return cls.__num
        
    obj = A()
    print(obj.get_num())
    
  10. 静态方法:通过装饰器 @staticmethod 进行修饰,静态方法即不需要传递类和对象的方法,有利于减少不必要的内存占用和性能消耗。

    class A(object):
        @staticmethod
        def info_print():
            print('这是A类')
    

六.异常

  1. 异常的定义:解释器检测到错误时无法继续执行,并出现一些错误的提示,这就是所谓的异常

    异常的作用:使得解释器检测到错误时,转而执行另一句没错误的语句,使得程序不因一个错误而停止下来。

  2. 基本写法

    try:
        可能发生错误的代码
    except:
        出现异常时执行的代码
    else:
        没有异常时执行的代码
    finally:
    	无论是否异常都要执行的代码
    

    体验案例:

    #需求:尝试以r模式打开文件,若文件不存在(发生错误),则以w方式打开
    try:
        f = open('test.txt','r')
    except:
        f = open('test.txt','w')
    
  3. 捕获指定异常

    try:
        print(num)
    except (NameError, ZeroDivisionError) as result:
        print(result)  #捕获的异常描述信息
        num = 777
        print(num)
       
    #若尝试执行代码的异常类型和要捕获的异常类型不一致,则无法捕获异常
    #一般try下方只放一行尝试执行的代码
    
  4. 捕获所有异常:利用 Exception 类

    #Exception是所有程序异常类的父类
    try:
        可能错误的代码
    except Exception as result:
        print(result)
    
  5. 异常中的 else 和 finally:

    try:
        f = open('test.txt','r')
    except Exception as result:
        f = open('test.txt','w')
        print(result)
    else:  # try 下方的代码无异常时执行的代码
        print('代码没有异常和错误')
    finally:  #无论有无异常都要执行的代码,如关闭文件
        f.close()
    
  6. 异常的传递

    import time
    try:
        f = open('test.txt') #默认打开模式为只读
        #尝试循环读取内容
        try:
            while True:
                con = f.readline()
                #无内容时退出循环
                if len(con) == 0:
                    break
                time.sleep(2)
                print(con)
        except:
            #在命令提示符中按下 Ctrl+C 终止程序
            print('程序被意外终止')
    except:
        print('文件不存在')
    
  7. 自定义异常: 抛出自定义异常的语法为raise 异常类对象

    #自定义异常类,继承Exception
    class ShortInputError(Exception):
        def __init__(self,length,min_length):
            self.length=length
            self.min_length=min_length
    
        #设置抛出异常的描述信息
        def __str__(self):
            return f'输入长度为{self.length},不能少于{self.min_length}个字符'
    
    def main():  #封装代码
        try:
            con = input('请输入密码: ')
            if len(con) < 6:
                raise ShortInputError(len(con),6)
        except Exception as result:
            print(result)
        else:
            print('密码输入完成')
            
    main()
    

七.模块

  1. 了解模块:Python模块(Module),是一个Python文件,包含了Python对象定义和语句。

  2. 导入和调用模块

    #导入及调用模块
    
    #写法一
    import 模块名  #导入模块中的所有代码
    模块名.功能名()
    
    #写法二
    from 模块名 import 功能1,功能2...  #单个调用某功能
    功能名()   #即不需要在功能前写 "模块名."
    
    #写法三
    from 模块名 import *
    功能名()  
    
    #一般用第一种写法
    

    利用as定义别名:定义别名后,使用时要用定义的别名

    #模块定义别名
    import 模块名 as 别名
    
    #功能定义别名
    from 模块名 import 功能 as 别名
    
  3. 制作模块:模块名字就是py文件的名字。自定义模块名必须要符合标识符命名规则

    #只会在当前文件中调用下列测试代码,其他导入的文件内不符合该条件,也就不会执行测试代码
    # __name__ 是系统变量,是模块的标识符。如果在自身模块里,则其值为 '__main__';否则是所在模块的名字
    if __name__ == '__main__':
        测试模块功能代码
    
  4. 模块定位顺序:当导入一个模块,Python解释器对模块位置的搜索顺序是:

    当前目录 > 搜索在shell变量PYTHONPATH下的每个目录 > 操作系统的默认python路径

    注意

    自己的文件名不要和已有模块名重复,否则模块功能无法使用。

    使用from 模块名 import 功能时,若功能名字重复,则调用最后定义的或最后导入的功能。

    当使用 import 模块名 的写法调用模块时,不需要担心功能名重复。

  5. __all__列表:如果一个模块文件中有__all__ 变量列表,当使用from 模块名 import *导入该模块时,则只能导入__all__列表中的元素。

  6. :包将有联系的模块组织在一起,放到同一个文件夹下,并且在这个文件夹内自动生成一个名字为__init__.py的文件,这个文件控制着包的导入行为。

    创建包:在Pycharm中 New -> Python Package -> 输入包名 - > [OK] 即可新建一个包。

    导入包

    #方法一
    import 包名.模块名
    包名.模块名.功能
    
    #方法二
    #注意,必须在 __init__.py 文件中添加 __all__ = [] 来控制允许导入的模块列表
    from 包名 import *
    模块名.功能
    

面向对象综合实例

#使用面向对象编程思想完成学员管理系统的开发

#为了方便维护代码,一般一个角色一个程序文件
#项目要有主程序入口,习惯为main.py

#系统要求:学员数据存储在文件中
#系统功能:添加学员、删除学员、修改学员信息、查询学员信息、显示所有学员信息、保存学员信息、退出系统等功能


#student.py
#学员类
class Student(object):
    def __init__(self,name,gender,tel):
        #姓名、性别、手机号
        self.name = name
        self.gender = gender
        self.tel = tel

    def __str__(self):
        return f'{self.name},{self.gender},{self.tel}'


#mangerSystem.py
#存储数据的: student.data
#存储数据的形式: 列表存储学员对象
#系统功能: 添加、删除、修改、查询、显示、保存学员信息

#管理系统类
class StudentManager(object):
    def __init__(self):
        #存储数据所用列表
        self.student_list = []

    #一. 程序入口函数,启动程序后执行的函数
    def run(self):
        #1. 加载学员信息
        self.load_student()

        while True:
            #2. 显示功能菜单
            self.show_menu()
            #3. 用户输入目标功能序号
            menu_num = int(input('请输入您需要的功能序号: '))

            #4. 根据用户输入的序号执行相应功能
            if menu_num == 1:
                # 添加学员
                self.add_student()

            elif menu_num == 2:
                # 删除学员
                self.del_student()

            elif menu_num == 3:
                # 修改学员信息
                self.modify_student()

            elif menu_num == 4:
                # 查询学员信息
                self.search_student()

            elif menu_num == 5:
                # 显示所有学员信息
                self.show_menu()

            elif menu_num == 6:
                # 保存学员信息
                self.save_student()

            elif menu_num == 7:
                # 退出系统 - 退出循环
                break

    #二. 系统功能函数
    #2.1 显示功能菜单 -- 静态方法
    @staticmethod
    def show_menu():
        print('请选择如下功能: ')
        print('1.添加学员')
        print('2.删除学员')
        print('3.修改学员信息')
        print('4.查询学员信息')
        print('5.显示所有学员信息')
        print('6.保存学员信息')
        print('7.退出系统')

    #2.2 添加学员
    def add_student(self):
        #1. 用户输入
        name = input('请输入姓名: ')
        gender = input('请输入性别: ')
        tel = input('请输入手机号: ')

        #2. 创建学员对象 -- 先导入student.py模块
        student = Student(name,gender,tel)

        #3. 将对象添加到学员列表
        self.student_list.append(student)

    #2.3 删除学员
    def del_student(self):
        #1. 用户输入目标学员姓名
        del_name = input('请输入要删除的学员姓名:')

        #2. 如果用户输入的目标学员存在则删除,否则提示不存在
        for i in self.student_list:
            if i.name == del_name:
                self.student_list.remove(i)
                break
        else:
            print('查无此人!')

    #2.4 修改学员信息
    def modify_student(self):
        #1. 用户输入目标学员姓名
        modify_name = input('请输入要修改的学员姓名: ')

        #2. 如果用户输入的目标学员存在,则修改信息,否则提示不存在
        for i in self.student_list:
            if i.name == modify_name:
                i.name = input('请输入学员姓名: ')
                i.gender = input('请输入学员性别: ')
                i.tel = input('请输入学员手机号: ')
                print('修改成功!')
                break
        else:
            print('查无此人!')

    #2.5 查询学员信息
    def search_student(self):
        #1. 用户输入目标学员姓名
        search_name = input('请输入要查询的学员姓名: ')

        #2. 若存在,打印学员信息,否则提示不存在
        for i in self.student_list:
            if i.name == search_name:
                print(f'姓名{i.name},性别{i.gender},手机号{i.tel}')
                break
        else:
            print('查无此人!')

    #2.6 显示所有学员信息
    def show_student(self):
        print('姓名\t性别\t手机号')
        for i in self.student_list:
            print(f'{i.name}\t{i.gender}\t{i.tel}')

    #2.7 保存学员信息
    def save_student(self):
        # 拓展 __dict__方法,以字典方式返回类和对象内的属性
        #1. 打开文件
        f = open('student.data','w')

        #2. 文件写入学员数据 - 先将学员对象数据转换成列表字典数据再做存储
        new_list = [i.__dict__ for i in self.student_list]
        # 文件内数据要求为字符串类型,故要先转换数据类型为字符串才能写入文件
        f.write(str(new_list))

        #3. 关闭文件
        f.close()

    #2.8 加载学员信息
    def load_student(self):
        #尝试以"r"模式打开数据文件,有异常则用"w"模式打开;存在则读取数据
        try:
            f = open('student.data','r')
        except:
            f = open('student.data','w')
        else:
            #1. 读取数据
            data = f.read()

            #2. 先将文件中的 字符串型字典数据 转换为 对象数据 后再存储到学员列表
            new_list = eval(data)
            self.student_list = [Student(i['name'],i['gender'],i['tel']) for i in new_list]

        finally:
            #3. 关闭文件
            f.close()

#main.py

#导入模块
#from managerSystem import *

#启动管理系统
#if __name__ == '__main__':
student_manager = StudentManager()
student_manager.run()

猜你喜欢

转载自blog.csdn.net/BRoctopus/article/details/109187403
今日推荐