【详细】Python基础(完结篇)

15. 异常

在Python中,程序在执行的过程中产生的错误称为异常。 如列表所以越界、打开不存在的文件等。
 

15.1 异常类

 

NameError: 尝试访问一个未声明的变量,会引发NameError。

ZeroDivisionError: 当除数为零的时候,会引发ZeroDividionError异常。

SyntaxError: 当解释器发现语法错误时,会引发SyntaxError异常。

IndexError: 当使用序列中不存在的索引时,会引发IndexError异常。

KeyError: 当使用字典中不存在的键访问值时,会引发KeyError异常。
 

15.2 异常处理

 

Python处理异常的能力非常强大,它可以准确地反馈错误信息,帮助开发人员准确定位到问题发生的位置和原因。Python中使用try-except语句处理异常。其中,try语句用于检测异常,except语句用于捕获异常。
 

 

15.2.1 体验异常

 

# 1. 需求:尝试打开test.txt(r)  如果文件不存在,只写方式打开w
'''
try:
    可能发生错误的代码
except:
    发生错误的时候执行的代码
'''

try:
    f = open('test.txt','r')
except:
    f = open('test.txt','w')

 

15.2.2 捕获指定异常

 

# 需求:尝试执行打印num,捕获异常类型NameError. 如果捕获到这个异常类型,执行打印,'有错误'
try:
    print(num)    # 可能发生的错误
except NameError:  # 异常类型
    print('有错误')   # 如果捕获到该异常类型执行的代码

'''
注意:
    1. 如果尝试执行的代码的异常类型和要捕获的异常类型不一致,则无法捕获异常。
    2. 一般try下方只放一行尝试执行的代码
'''

 

15.2.3 捕获多个指定异常

 

# 尝试执行的代码,并不能断定它的异常类型具体是什么,在except后用元组的方式,把可能的异常类型全都书写里面
try:
    print(1/0)
except (NameError, ZeroDivisionError):
    print('有错误')

 

15.2.4 捕获异常描述信息
try:
    print(1/0)
except (NameError, ZeroDivisionError) as result:
    print(result)  # division by zero

 

15.2.5 捕获所有异常

 

# 尝试执行打印num, 捕获Exception 打印异常描述信息
try:
    print(num)
except Exception as result:
    print(result)
    
# Exception是所有程序异常类的父类
# 不需要程序员指定具体的异常类型
# 捕获所有异常就是去except捕获这个Exception,从而做到捕获了父类,即捕获到了具体的某个异常类

 

15.2.5 else和finally

 

else


'''
else表示的是如果没有异常要执行的代码
'''
try:
    print(1)
except Exception as result:
    print(result)
else:
    print('我是else,当没有异常的时候执行的代码')

finally

# 需求:尝试以r打开文件,如果有异常以w打开这个文件,最终关闭文件
'''
finally表示的是无论是否异常都要执行的代码,例如关闭文件
'''
try:
    f = open('test300.txt','r')
except Exception as e:
    print(e)
    f = open('test300.txt','w')

finally:
    f.close()

 

15.3 异常的传递

 

'''
# 异常的传递指代的就是我们的异常是可以嵌套书写的,要去了解嵌套书写异常语句的时候,
    我们的程序执行流程是什么.
# 这些要学习的知识点简称为异常的传递
# 如果书写打开访问模式,不写访问模式,那么默认即为只读r模式
# 先执行外层的try、except,然后在执行内层的try、except
'''

'''
需求1:尝试只读打开test.txt 文件存在读取内容,不存在提示用户
需求2:读取内容:循环读取,当无内容的时候退出循环,如果用户意外终止,提示用户已经意外终止
'''
import time
try:
    f = open('test.txt')
    # 尝试循环读取内容
    try:
        while True:
            con = f.readline()
            # 如果读取完成退出循环
            if len(con) == 0:
                break
            time.sleep(3)
            print(con)
    except:
        # 在命令提示符中如果按下ctrl+c结束符终止的键
        print('程序被意外终止')
except:
    print('该文件不存在')

 

15.4 自定义异常

 

'''
自定义异常的作用:用来我们将不满足程序逻辑的情况,进行一个反馈,报错给用户。
用来报错,报的错误不是语法错误,而是不符合我们程序逻辑要求的错误。
'''

# 1.定义异常类,继承Exception 魔法方法有init和str(设置异常描述信息)
class ShortInputError(Exception):
    def __init__(self, length, min_len):
        # 用户输入的密码长度
        self.length = length
        # 系统要求的最少长度

        self.min_len = min_len

    # 设置异常描述信息
    def __str__(self):
        return f'您输入的密码长度是{self.length},密码不能少于{self.min_len}'

def main():
    # 2. 抛出异常:尝试执行:用户输入密码,如果长度小于3,抛出异常
    try:
        password = input('请输入密码:')
        if len(password) < 3:
            # 抛出异常类创建的对象
            # ShortInputError(len(password),3)抛出了一个对象而已。可以理解raise相当于原来的打印。打印对象的时候,打印到的就是str魔法对象的返回值。
            # raise抛出这个对象的时候,我们捕获的时候,捕获到的也是str魔法方法的返回值
            raise ShortInputError(len(password),3)
    # 3. 捕获该异常
    except Exception as result:
        print(result)

    else:
        print('没有异常,密码输入完成')

main()

 
 

15.5 小总结

 

'''
1. 异常语法

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

2. 捕获异常

except 异常类型:
    代码
except 异常类型 as xx:
    代码

3. 自定义异常

# 1.自定义异常类
class 异常类类名(Except):
    代码

    # 设置抛出异常的描述信息
    def __str__(str):
        return ...

# 2. 抛出异常
raise 异常类名()

# 捕获异常
except Exception...
'''

 

16. Python模块

 

16.1 模块的基本使用

 

# 模块就是一个python文件,直接调用这个模块里的功能,省去了自己定义功能再使用的步骤。
# 不推荐一次性导入多个模块,推荐的是跟一个模块名

# 需求:math模块下sqrt()开平方计算

# 方法一:import 模块名     模块名.功能
import math
print(math.sqrt(9))  # 3.0
# 再python当中,涉及到类似于除法计算不管参与计算的数字是否有浮点数,将来反馈回来的结果一定是浮点数。

# 方法二:from 模块名 import 功能1,功能2...    直接功能调用
from math import sqrt
print(sqrt(9))

# 方法三:from math import *      直接功能调用
from math import *
print(sqrt(9))  

定义别名

# 需求:运行后暂停2秒打印hello
'''
1. 导入time模块或导入time模块的sleep功能
2. 调用功能
3. 打印hello
'''

# 1.  模块别名    注意:如果定义了别名之后就只能使用别名
# import time as tt
# tt.sleep(2)
# print('hello')

# 2. 定义别名
from time import sleep as sl
sl(2)
print('hello')

16.2 模块的制作

在当前文件夹中创建my_module1.py,然后在调用自己制作的模块。
 

my_module1.py

# 需求:一个函数,完成任意两个数字加法运算
def testA(a, b):
    print(a + b)

# 测试信息
# testA(1, 1)
# print(__name__)

# 为了不频繁的删除测试信息或添加测试信息,这时可以加一个判断
# __name__是系统变量,是模块的标识符,值是:如果是自身模块值是__main__,否则是当前的模块的名字
if __name__ == '__main__':
    testA(1,1)

 

在下面的程序里调用my_module1.py模块

'''
再python程序当中,每个模块就是一个python文件,这个python文件都有自己的名字。
name是一个系统变量,是模块的标识符,是每个python文件的标识符,如果name的使用位置再在自身模块里
那么它的值就是__main__,否则不在自身模块里面,那么这个name的值就是我们模块的名字,即是我们的python文件名。
'''
# 1. 导入模块
import my_module1

# 2. 调用功能
my_module1.testA(2,2)

 
 

16.3 模块的定位顺序

 

'''

当导入一个模块,Python解析器对模块的搜索顺序是:
1. 当前目录
2. 如果不在当前目录,Python则搜索shell变量PYTHONPATH下的每个目录(安装解释器目录下的)
3. 如果都找不到,Python会查看默认路径。UNIX下,默认路径一般为/usr/local/lib/python(一般不涉及到默认路径)

模块搜索路径存储在system模块的sys.path变量中。变量里包含当前目录,PYTHONPATH和由安装过程决定的默认目录

注意:
    自己的文件名不要和已有的模块名重复,否则导致模块功能无法使用
    使用from 模块名 import 功能的时候,如果功能名字重复,调用到的是最后定义或导入的功能
'''

# 1. 自己的模块名不能和已有的模块名重复
import random
num = random.randint(1,5)  # 因为在当前目录中有一个random模块,则报错
print(num)

 

16.4 all列表

'''
如果一个模块文件中有__all__变量,当使用from xxx import * 导入时,只能导入这个列表中的元素
'''
from my_module2 import *

testA()

# 因为testB函数没有添加all列表,只有all列表里面的功能才能导入
# testB()

 

下面就是my_module2.py中的代码

# 有all列表控制着导入行为,导致只导入all列表里面的功能。

# 1. 定义多个功能,把某个功能添加到__all__
__all__ = ['testA']

def testA():
    print('testA')

def testB():
    print('testB')

 

16.5 导入包

创建了一个名为mypackage的包,里面有三个文件

在这里插入图片描述
 

__init__.py
 

__all__ = ['my_module1']

 

mymodule1.py

print(1)

def info_print():
    print('my_module1')
    

 

mymodule2.py

print(2)

def info_print():
    print('my_module2')

 
这个就是导入包.py(尽量不要起中文名称),开始导包
 

'''
# 包将有联系的模块组织在一起,即放到同一个文件夹下,并且在这个文件夹创建一个名字为__init__.py文件,那么这个文件就称为包
# 当右键去创建包的时候,这个文件夹里面会自动创建一个名字为__init__.py的文件,这个文件可以控制包的导入行为

'''

# 方法一
'''
1. 导入
import 包名.模块名
2. 调用功能
包名.模块名.功能()
'''
# 导入mypackage包下的模块1,使用这个模块内的info_print1函数
# import mypackage.my_module1
# mypackage.my_module1.info_print()


# 方法二:注意 设置__init__.py文件里面的all列表( __all__ = [] ),添加的是允许导入的模块
'''
from 包名 import *
模块名.目标
'''
from mypackage import *
my_module1.info_print()

 

16.5 拓展小知识

 

# 在工作岗位下,避免功能名字重复这个事情发生

# 1. 当使用from xx  import 功能
# 导入模块功能的时候,如果功能名字重复,导入的时候后定义或后导入的这个同名功能

def sleep():
    print('我是自定义的sleep')

from time import sleep

# 后导入的同名功能(这时就会报错)
# def sleep():
#     print('我是自定义的sleep')
sleep(2)



# 2. 拓展:名字重复
# 问题:import 模块名 时候担心名字重复的问题-不需要(因为功能名一样但是模块名不一样)
import time
print(time)

time = 1   # 这个变量会覆盖模块的功能
print(time)

# 问题:为什么变量也能覆盖模块?-- 在Python语言中,数据是通过 引用 传递的

 

16.6 小总结

 

'''
什么是模块? 模块就是一个python文件,这个文件里面有大量的变量,或者是函数、类,这是一个普通的python文件
可以书写大量的python程序,这个python程序书写完成之后,可以用以下的三种方法进行导入。其他文件能灵活的调用
这个模块当中的功能。

导入模块方法
    import 模块名
    from 模块名 import 目标
    from 模块名 import *

导入包
    import 包名.模块名
    from 包名 import *   ( __all__ = [] : 允许导入的模块或功能列表)
'''

 

17. 学生管理系统

思路:
1.首先先创建一个项目目录StudentManagerSystem。这个是面向对象的学生管理系统,一共有两个角色(两个类),一个是学生,一个是管理系统。为了方便维护代码,一般一个角色一个程序文件。项目由主程序入口,习惯为main.py。
2. 学生类里面有学生的基本信息,当创建一个学生对象的时候,会显示学生的信息(__str__)
3. 管理系统类里面有程序入口,提供功能界面,每个功能由每个函数实现,然后再去调用。功能主要增、删、改、查学生,显示所有学员信息,保存学员信息,加载学员信息。

 
 
在这里插入图片描述
 
main.py

# 程序入口文件功能的学习,程序入口文件:运行这个文件就可以启动这个管理系统。
# 1. 导入关系系统模块
from managerSystem import *
# 2. 启动管理系统
# 保证是当前文件运行才启动管理系统:if -- 创建对象并调用run方法
if __name__ == '__main__':   # 这个__name__意思:在本程序中执行就等于__main__,其他文件调用就不等于__main__.
    student_manager = StudentManager()
    student_manager.run()

 
managerSystem.py

from student import *
class StudentManager(object):
    def __init__(self):
        # 储存学员数据 -- 列表
        self.student_list = []
# 程序的入口一般定义为run函数名,这是程序员的习惯。从键盘输入的内容都是字符串,需要用int进行转换

    # 一、程序入口函数
    def run(self):
        # 1. 加载文件里面的学员数据
        self.load_student()
        while True:
             # 2. 显示功能菜单
             self.show_menu()
             # 3. 用户输入目标功能序号
             menu_num = int(input('请输入您需要的功能序号:'))
             # 4. 根据用户输入的序号执行不同的功能 -- 如果用户输入1,执行添加
             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_student()
             elif menu_num == 6:
                 # 保存学员信息
                self.save_student()
             elif menu_num == 7:
                 # 退出系统 -- 退出循环
                break


# 这里面不涉及对象或对象数据的使用,在面向对象编程的时候,这样的函数需要定义成静态方法。
# 在类里面书写代码,在类里面调用实例方法的写法是self.函数名
    # 二、系统功能函数
    # 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):
        pass
        # 1. 用户输入姓名、性别、手机号
        name = input('请输入您的姓名:')
        gender = input('请输入您的性别: ')
        tel = input('请输入您的手机号:')

        # 2. 创建学员列表 -- 类?类在student文件里面 先导入student模块,在创建对象
        student = Student(name, gender, tel)

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

        print(self.student_list)
        print(student)

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

        # 2. 遍历学员列表,如果用户输入的学员存在则删除学员对象,否则提示学员不存在
        for i in self.student_list:
            if del_name == i.name:
                # 删除学员对象
                self.student_list.remove(i)
                break
        else:
            # 循环正常结束执行的代码:循环结束都没有删除一个对象,所以说明用户输入的目标学员不存在
            print('查无此人')

        print(self.student_list)

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

        # 2. 遍历列表数据,如果学员存在修改姓名性别手机号,否则提示学员不存在
        for i in self.student_list:
            if modify_name == i.name:
                i.name = input('姓名:')
                i.gender = input('性别:')
                i.tel = input('手机号:')
                print(f'修改学员信息成功,姓名{i.name}, 性别{i.gender}, 手机号{i.tel}')
                break
        else:
            print('查无此人')

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

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

    # 2.6 显示所有学员信息
    def show_student(self):
        # 1. 打印表头
        print('姓名\t性别\t手机号')

        # 2. 打印学员数据
        for i in self.student_list:
            print(f'{i.name}\t\t{i.gender}\t\t{i.tel}')

    # 2.7 保存学员信息
    def save_student(self):
        # 1. 打开文件
        f = open('student.data', 'w')

        # 2. 文件写入数据
        # 2.1 [学员对象] 转换成 [字典]
        new_list = [i.__dict__ for i in self.student_list]

        # 2.2 文件写入 字符串数据  (转化成字符串才能写入文件)
        f.write(str(new_list))

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

    # 2.8 加载学员信息
    def load_student(self):
        # 1. 打开文件:尝试r打开,如果有异常w
        try:
            f = open('student.data', 'r')
        except:
            f = open('student.data', 'w')
        else:
            # 2. 读取数据:文件读取出的数据是字符串 还原列表类型:[{}] 转换 [学员对象]
            data = f.read() # 字符串
            new_list = eval(data) # 还原列表类型,eval把字符串里面的列表这样的数据类型转换成列表原本类型
            self.student_list = [Student(i['name'], i['gender'], i['tel']) for i in new_list] # 获取到每个key的值
        finally:
            # 3. 关闭文件
            f.close()

 
student.py

'''
需求:
    学员信息包含:姓名、性别、手机号
    添加__str__魔法方法,方便查看学员对象信息
'''
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}'

# aa = Student('aa', 'nv' , 111)
# print(aa)

 
小拓展__dict__

这个知识点在managerSystem.py文件中用到了,所以学习一下。

'''
拓展:
    __dict__是面向对象编程当中类对象或者是实例都拥有的属性,这个属性的作用是收集类对象或者实例对象的属性和方法
    以及对应的值,从而返回一个字典。
'''
# 1. 定义类
class A(object):
    a = 0

    def __init__(self):
        self.b = 1

# 2. 创建对象
aa = A()

# 3. 调用__dict__

# 返回类内部所有属性和方法对应的字典
print(A.__dict__)

# 返回实例属性和值组成的字典
print(aa.__dict__)  # {'b': 1}

 
小总结

这是学生管理系统所用的知识点,基本上覆盖了所学的基础知识。查漏补缺,复习巩固。

'''
函数:
    定义和调用
    参数的使用
面向对象:
    定义类
    创建对象
    定义和调用实例属性
    定义和调用实例方法
数据类型:
    列表
        增加删除数据
        列表推导式
    字典
    字符串
文件操作:
    打开文件
    读取或写入(读取出来的数据和写入的数据数据类型必须是字符串类型)
    关闭文件
'''
  • 17
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值