首页 > 其他分享 >异常捕获列表字典推导式

异常捕获列表字典推导式

时间:2024-04-15 21:45:20浏览次数:22  
标签:推导 异常 列表 try user print input data 字典

【一】什么是异常

  • 异常是程序运行时可能发生的错误或意外情况。在Python中,异常是一种对象,表示程序执行期间发生的错误。
  • 当出现异常时,程序的正常流程会被中断,而是跳转到异常处理流程。

【二】异常分类

  • 在Python中,异常分为两类:
    • 内建异常(Built-in Exceptions):由Python内部定义的异常,例如ZeroDivisionErrorNameError等。
    • 用户自定义异常:由程序员自己定义的异常,用于满足特定的业务需求。

【1】BaseException(所有异常的基类)

  • SystemExit:解释器请求退出
  • KeyboardInterrupt:用户中断执行(通常是输入^C)
  • Exception:常规错误的基类
  • StopIteration:迭代器没有更多的值
  • GeneratorExit:生成器(generator)发生异常来通知退出
  • StandardError:所有的内建标准异常的基类
  • ArithmeticError:所有数值计算错误的基类
  • FloatingPointError:浮点计算错误
  • OverflowError:数值运算超出最大限制
  • ZeroDivisionError:除(或取模)零 (所有数据类型)
  • AssertionError:断言语句失败
  • AttributeError:对象没有这个属性
  • EOFError:没有内建输入,到达EOF 标记
  • EnvironmentError:操作系统错误的基类
  • IOError:输入/输出操作失败
  • OSError:操作系统错误
  • WindowsError:系统调用失败
  • ImportError:导入模块/对象失败
  • LookupError:无效数据查询的基类
  • IndexError:序列中没有此索引(index)
  • KeyError:映射中没有这个键
  • MemoryError:内存溢出错误(对于Python 解释器不是致命的)
  • NameError:未声明/初始化对象 (没有属性)
  • UnboundLocalError:访问未初始化的本地变量
  • ReferenceError:弱引用(Weak reference)试图访问已经垃圾回收了的对象
  • RuntimeError:一般的运行时错误
  • NotImplementedError:尚未实现的方法
  • SyntaxError:Python 语法错误
  • IndentationError:缩进错误
  • TabError:Tab 和空格混用
  • SystemError:一般的解释器系统错误
  • TypeError:对类型无效的操作
  • ValueError:传入无效的参数
  • UnicodeError:Unicode 相关的错误
  • UnicodeDecodeError:Unicode 解码时的错误
  • UnicodeEncodeError:Unicode 编码时错误
  • UnicodeTranslateError:Unicode 转换时错误

【2】warning(警告的基类)

  • DeprecationWarning:关于被弃用的特征的警告
  • FutureWarning:关于构造将来语义会有改变的警告
  • OverflowWarning:旧的关于自动提升为长整型(long)的警告
  • PendingDeprecationWarning:关于特性将会被废弃的警告
  • RuntimeWarning:可疑的运行时行为(runtime behavior)的警告
  • SyntaxWarning:可疑的语法的警告
  • UserWarning:用户代码生成的警告

【三】触发异常

  • 我们可以使用raise语句自己触发异常
raise [Exception [, args [, traceback]]]
  • 语句中 Exception 是异常的类型

    • (例如,NameError)参数标准异常中任一种,args 是自已提供的异常参数。
    • 最后一个参数是可选的(在实践中很少使用),如果存在,是跟踪异常对象。
  • 一个异常可以是一个字符串,类或对象。

    • Python的内核提供的异常,大多数都是实例化的类,这是一个类的实例的参数。
    • 定义一个异常非常简单,如下所示:
def functionName( level ):
    if level < 1:
        raise Exception("Invalid level!", level)
        # 触发异常后,后面的代码就不会再执行
  • 为了能够捕获异常
    • "except"语句必须有用相同的异常来抛出类对象或者字符串。
  • 例如我们捕获以上异常
    • "except"语句如下所示
try:
    正常逻辑
except Exception,err:
    触发自定义异常    
else:
    其余代码

【四】异常处理

  • 捕捉异常可以使用try/except语句。
    • try/except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理。
    • 如果你不想在异常发生时结束你的程序,只需在try里捕获它。
  • try的工作原理是,当开始一个try语句后,python就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try子句先执行,接下来会发生什么依赖于执行时是否出现异常。
    • 如果当try后的语句执行时发生异常,python就跳回到try并执行第一个匹配该异常的except子句,异常处理完毕,控制流就通过整个try语句(除非在处理异常时又引发新的异常)。
    • 如果在try后的语句里发生了异常,却没有匹配的except子句,异常将被递交到上层的try,或者到程序的最上层(这样将结束程序,并打印默认的出错信息)。
    • 如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话),然后控制流通过整个try语句。

【1】异常捕获语法

[1]语法

try:
    # 正常可能会触发异常的代码
except ExceptionType as e:
    # 触发异常后执行的代码

[2]示例

try:
    name = "Dream"
    name[0] = 'd'
except Exception as e:
    print(f"触发异常 :>>>> {e}")

# 触发异常 :>>>> 'str' object does not support item assignment

[3]分析

  • 字符串不允许索引取值修改值,因此会报错
  • 报错后被except语句捕获到,并将异常信息打印出来

【2】不带任何异常类型使用except

[1]语法

try:
   # 正常的操作
   ...
except:
   # 发生异常,执行这块代码
   ...

[2]示例

try:
    result = 10 / 0
except:
    print("An error occurred")

# An error occurred

[3]分析

  • 在实际代码中不建议使用不带任何异常类型的except语句,因为它会捕获所有异常,包括程序中可能不期望捕获的异常,使得排查问题变得困难。

【3】异常分支语法

[1]语法

try:
    # 正常的操作
    ...
except:
    # 发生异常,执行这块代码
    ...
else:
    # 如果没有异常执行这块代码
    ...

[2]示例

try:
    age = int(input("请输入你的年龄: "))
except ValueError:
    print("Invalid input! Please enter a valid integer.")
else:
    print(f"You entered: {age}")

[3]分析

  • 异常分支语法中的else块中的代码在没有异常发生时执行,它提供了一种清晰的逻辑结构,可以更好地组织代码。

【4】使用相同的except语句来处理多个异常信息

[1]语法

try:
    # 正常的操作
    ...
except(Exception1[, Exception2[, ...ExceptionN]]]):
    # 发生以上多个异常中的一个,执行这块代码
    ...
else:
    # 如果没有异常执行这块代码
    ...

[2]示例

try:
    result = 10 / 0
except (ZeroDivisionError, TypeError) as e:
    print(f"Error: {e}")
else:
    print("No exception occurred")

[3]分析

  • 通过使用相同的except语句处理多个异常,可以简化代码并提高可读性。
  • 多个异常类型可以放在一个元组中,用括号括起来

【5】无论是否发生异常都将执行最后的代码

[1]语法

try:
	# 正常执行的代码
    ...
except:
    # 发生异常,执行这块代码
finally:
	#退出try时总会执行
    ...

[2]示例

try:
    result = 10 / 0
except ZeroDivisionError as e:
    print(f"Error: {e}")
finally:
    print("Finally block is executed")

[3]分析

  • finally块中的代码无论是否发生异常都将被执行,常用于资源的释放、清理等操作

【五】列表字典推导式

【1】语法

  • 列表推导式可以利用列表,元组,字典,集合等数据类型,快速的生成一个特定需要的列表。
  • 语法格式如下
[表达式 for 迭代变量 in 可迭代对象 [if 条件表达式]]

【2】列表推导式

number_list = []
for i in range(5):
    number_list.append(i)

print(number_list) # [0, 1, 2, 3, 4]

number_list = [i for i in range(5)]
print(number_list)  # [0, 1, 2, 3, 4]
test = [1, 2, 3]

print([i * i for i in test])
# [1,4,9]

print([[i, i + 2] for i in test])
# [[1,3],[2,4],[3,5]]
# 原始列表 : 每个元素都有空格
some_animals = [' dog', 'cat  ', ' sheep ']

# 列表生成式: 新的列表,每个元素都去除掉了空格
some_animals_new = [i.strip() for i in some_animals]
print(some_animals_new)
# ['dog','cat','sheep']
test_1 = [1, 2, 3]
test_2 = [4, 5, 6]

# 列表生成式 : 遍历两个列表并取出每一个列表的元素 做乘法运算
list_one = [x * y for x in test_1 for y in test_2]
print(list_one)
# [4,5,6,8,10,12,12,15,18]

# 列表生成式 : 遍历两个列表并取出每一个列表的元素 做新列表的生成
list_two = [[x, x + y] for x in test_1 for y in test_2]
print(list_two)
# [[1, 5], [1, 6], [1, 7], [2, 6], [2, 7], [2, 8], [3, 7], [3, 8], [3, 9]]

###  注意通过这两个print体会谁是内层循环,谁是外层循环

# 列表生成式 : 遍历两个列表并取出每一个列表对应索引的元素 做乘法运算
list_three = [test_1[i] * test_2[i] for i in range(len(test_1))] #len(test_1) = 3 
print(list_three)
# [4, 10, 18]

# 列表生成式 : 遍历两个列表并取出每一个列表对应索引的元素 做乘法运算
list_four = [x * y for x, y in zip(test_1, test_2)]
print(list_four)
# [4, 10, 18]
test = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]

list_new = [[row[i] for row in test] for i in range(len(test[0]))] # len(test[0]) = 4

print(list_new)
# [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
test = [1, 2, 3, 4, 5, 6]
list_one = [x for x in test if x % 2 == 0]
print(list_one)
# [2, 4, 6]

list_two = list(filter(lambda x: x % 2 == 0, test))
print(list_two)
# [2, 4, 6]

【3】字典推导式

# user_data_dict = {}
# with open('user_data.text','r',encoding='utf8') as fp:
#     for line in fp:
#         username,password = line.strip().split('|')
#         user_data_dict[username] = password
# print(user_data_dict)


# with open('user_data.text', 'r', encoding='utf8') as fp:
#     user_data_dict = {line.strip().split('|')[0]: line.strip().split('|')[1] for line in fp}
# print(user_data_dict)

【4】元组生成式

# ----> 先别管 生成的是生成器对象  后边学
# num_tuple = (i for i in range(10))
# # ---> (0,9)
# print(tuple(num_tuple))

【5】集合推导式

#  类似 列表推导式
# set_num = {i for i in range(10)}
# print(set_num)

练习

# 【全局异常捕获】
# 在指定位置添加异常捕获机制
# 如果遇到异常和报错要捕获异常信息并做定制化输出

# 【总需求】
# 【1】打印功能菜单供用户选择
# 【2】校验功能ID是否存在并且符合数字格式
# 【3】根据指定功能ID进入到指定的功能中

# 【注册功能】
# 【1】用户输入用户名和密码
# 【2】校验用户名是否存在,如果已经存在则禁止注册,否则允许注册
# 【3】使用文本文件作为数据存储位置
# 【4】用户注册时指定默认锁定状态为未锁定

# 【登录功能】
# 【1】用户输入用户名和密码
# 【2】校验用户名是否存在,如果不存在则提示注册
# 【3】校验用户状态是否是锁定状态,如果锁定不允许登录并提示管理员解除
# 【4】未锁定用户允许重试输入密码,最大重试次数为3次并提示剩余尝试次数
# 【5】用户输入密码错误次数达最大尝试次数后修改默认锁定状态为锁定

# 【文件拷贝功能】
# 【1】用户登录成功后允许使用文件拷贝程序
# 【2】用户输入指定的路径(源文件)
# (1)打开文件 (文本文件w 二进制是wb)
# (2)对文件类型做区分
# 【3】用户输入指定的路径(新文件)
# (1)复制当前文件到新位置
# (2)按照指定文件类型赋值新文件(可重命名或者使用原本的文件名)


# 【一】定制功能菜单
func_menu = '''
########################## 功能菜单 ########################## 
                            1.注册
                            2.登录
                            3.文件拷贝
                            3.退出(q)
'''

# 创建全局的用户信息字典
user_data_dict = {}
login_user_data = {
    'username': 'dream',
    'is_locked': False,
}
# 【二】功能书写
while True:
    # 【1】打印功能菜单 ---> 让人家知道有什么功能
    print(func_menu)

    # 【2】让人家输入功能ID做校验
    func_id = input("请输入功能ID :>>>> ").strip()
    if func_id == 'q':
        print(f"欢迎下次光临!")
        break
    # (1)校验是否是数字类型
    if not func_id.isdigit():
        print(f"当前ID不是数字!")
        continue
    # (2)强制类型转换 ---字符串 --> 数字
    try:
        func_id = int(func_id)
    except Exception as e:
        print(f"当前ID不合法!")
        continue
    # (3)判断当前ID在我的功能菜单中
    if func_id not in [1, 2, 3]:
        print(f"当前功能ID不存在!")
        continue
    # 【3】映射视图函数 ---》 根据指定ID进入到指定功能中
    # 【4】在进入视图函数之前 ---> 先将所有用户数据读取出来 ---> 存放到指定的字典中
    try:
        with open('user_data.txt', 'r', encoding='utf8') as fp:
            # 得到的是一个列表 ---> 列表中的每一个元素存的数每一行额数据 包括换行符
            # 方式一:
            for line in fp:
                # ['dream', '521', '0']
                username, password, lock = line.strip().split(':')
                user_data_dict[username] = {
                    'username': username,
                    # 0 ---> False
                    # 数字 0 是假的
                    # 但是你现在是字符串 0
                    'password': password,
                    'is_locked': bool(int(lock))
                }
    except Exception as e:
        pass
    if func_id == 1:
        print(f"欢迎来到注册功能!")
        # 【1】输入用户名和密码
        username_input = input("请输入用户名 :>>>> ").strip()
        password_input = input("请输入密 码 :>>>> ").strip()
        # 【2】校验当前用户是否存在
        user_data = user_data_dict.get(username_input)
        if user_data:
            print(f"当前用户 :>>>> {username_input} 已经注册过!")
            continue
        # 【3】用户不存在则新建用户信息
        # 用户名:密码:锁定状态(默认是不锁定)
        user_data_str = username_input + ":" + password_input + ':' + '0'
        # 【4】写入用户数据
        with open('user_data.txt', 'a', encoding='utf-8') as fp:
            # 【5】写数据的时候注意 --->
            # 每一条用户数据都是一行而不是拼在一行
            fp.write(user_data_str + '\n')
        print(f"当前用户 :>>>> {username_input} 注册成功!")

    elif func_id == 2:
        print(f"欢迎来到登录功能!")
        if not user_data_dict:
            print(f"当前系统无用户注册!请先注册!")
            continue
        # 【1】输入用户名和密码
        username_input = input("请输入用户名 :>>>> ").strip()
        password_input = input("请输入密 码 :>>>> ").strip()
        # 【2】从当前的数据字典中获取到当前用户对象
        user_data = user_data_dict.get(username_input)
        if not user_data:
            print(f"当前用户 {username_input} 未注册!")
            continue
        # 【3】注册成功并且存在 ---> 校验当前用户的锁定状态
        # 正常没锁定是 false
        if user_data.get('is_locked'):
            print(f"当前用户已被锁定,请联系管理员解除!")
            continue
        # 【4】校验密码是否正确
        # 声明尝试次数和最大尝试次数
        count = 0
        max_retry = 3
        # 进入重试环节
        while count <= max_retry:
            count += 1
            # 第一次进来校验用户名和密码书否正确 ---> 如果正确应该直接断掉
            if password_input == user_data.get('password'):
                login_user_data['username'] = username_input
                login_user_data['is_locked'] = False
                print(f"当前用户 :>>>> {username_input} 登陆成功!")
                break
            if count == 3:
                # 尝试次数最大为3的时候进行锁定
                user_data_list = []
                with open('user_data.txt', 'r+', encoding='utf8') as fp:
                    # 得到的是一个列表 ---> 列表中的每一个元素存的数每一行额数据 包括换行符
                    for line in fp:
                        # line : dream:521:0\n
                        # ['dream', '521', '0']
                        username, password, lock = line.strip().split(':')
                        if username == username_input:
                            lock = '1'
                        # [username, password, lock] : ['dream', '521', '1']
                        # ':'.join([]) ---> dream:521:1
                        user_data_list.append([':'.join([username, password, lock]), '\n'])
                    # [['dream:521:1', '\n'], ['opp:666:0', '\n']]
                    fp.seek(0, 0)
                    for item in user_data_list:
                        # item : ['dream:521:1', '\n']
                        # dream:521:1\n
                        fp.writelines(item)
                print(f"当前用户密码尝试次数已达到最高,用户锁定,请联系管理员解除!")
                break
            print(f"当前用户密码错误")
            print(f"当前用户尝试次数还有 {max_retry - count} 次! ")
            password_input = input("请输入密 码 :>>>> ").strip()
            continue

    elif func_id == 3:
        print(f"欢迎来到当前文件拷贝功能")
        # 【1】输入源文件地址
        # (1)输入地址
        origin_path = input("请输入源文件地址 :>>>> ").strip()

        # (2)对文件后缀进行校验 文本 / 二进数据
        # D:\Python\PythonProjects\PythonProjects29\day12\user_data.txt
        try:
            type_file = origin_path.split('.')[-1]  # txt
            # 【2】打开源文件
            if type_file in ['txt', 'text']:
                with open(origin_path, 'r', encoding='utf8') as fp:
                    origin_data = fp.read()
            elif type_file in ['mp4', 'jpg', 'png', 'webp', 'jpeg', 'zip']:
                with open(origin_path, 'rb') as fp:
                    origin_data = fp.read()
        except:
            print(f"当前路径不存在!")

        # 【3】输入新文件地址
        target_path = input("请输入目标文件地址 :>>>> ").strip()
        target_file_name = input("请输入目标文件名 :>>>> ").strip()
        file_name, type_file = origin_path.split('\\')[-1].split('.')
        if target_file_name:
            target_file_name = target_file_name + '.' + type_file
        else:
            target_file_name = file_name + '.' + type_file
        # target_path : D:\Python\PythonProjects\PythonProjects29\day12
        # target_file_name : user_data.txt
        target_path = target_path + '\\' + target_file_name
        # 【4】写入新文件
        if type_file in ['txt', 'text']:
            with open(target_path, 'w', encoding='utf8') as fp:
                fp.write(origin_data)
        elif type_file in ['mp4', 'jpg', 'png', 'webp', 'jpeg', 'zip']:
            with open(target_path, 'wb') as fp:
                fp.write(origin_data)
        # 【5】打印写入完后才能
        print(f"当前目标文件 {target_file_name} 写入完成!")

标签:推导,异常,列表,try,user,print,input,data,字典
From: https://www.cnblogs.com/song1002/p/18136962

相关文章

  • Python列表推导式
    一、列表推导列表推导式又称推导列表。列表推导式是以列表为载体,以推导的方式将数据生成并放在列表中。推导即规则,它支持for循环和筛选模式(if判断模式)。设定一个既定规则在列表中进行数据生成,列表推导式比传统方法更为简洁,代价是放弃一部分的可读性。二、如何声明列表推导式最......
  • Android修改应用列表的失败学习
    没什么实用价值,一种记叙文和学习笔记的结合体。 0.回老家收到新需求:能不能处理一下这台旧手机,让我在家打上单位的钉钉打卡?旧手机型号华为荣耀7i,安卓版本4.0.3。看到华为两个字,我仿佛看到了我失败的未来。1. 首先想到的必然是虚拟定位。但钉钉显然会防范这种方法。搜索资料......
  • day 06-2 数据类型(列表)
    1.3公共功能1.相加,两个列表相加获取一个新的列表data=["张译","冯绍峰"]+["赵又廷","林更新"]print(data)#['张译','冯绍峰','赵又廷','林更新']v1=["赵又廷","林更新"]v2=["张译","冯......
  • day 06-3 数据类型(列表)
    1.6阶段作业1.写代码,有如下列表,按照要求实现每一个功能li=["linzai",'asff','wftthyy','kihfng',"张三四"]#计算列表的长度并输出data=len(li)#print(len(li))print(data)#5#列表中追加元素"seven"#列表中追加元素"seven",并输出添......
  • [POJ2891]Strange Way to Express Integers公式推导
    没啥事干,想着推个式子玩玩。题目链接题意不过多赘述,直接上过程:由题意得\[\begin{cases}x\equiva_1\,(mod\,\,n_1)\\x\equiva_2\,(mod\,\,n_2)\end{cases}\]展开得\[x=k_1·n_1+a_1=k_2·n_2+a_2\dots①\]移项得\[k_1·n_1=(a_2-a_1)+k_2·n_2\]\[k_1·n......
  • Tcl 列表操作
    1.列表命令集 列表相关命令 命令说明listarg1arg2...创建一个列表lindexlistindex返回列表list中的第index个元素(element)值llengthlist计算列表list元素个数lrangelistindex1index2返回指定范围内(从index1到index2)的元素lapp......
  • 查看自动类型推导结果的方法
    在《深入解析C++的auto自动类型推导》和《深入解析decltype和decltype(auto)》两篇文章中介绍了使用auto和decltype以及decltype和auto结合来自动推导类型的推导规则和用法,虽然确定类型的事情交给编译器去做了,但是在有的时候我们可能还是想知道编译器推导出来的类型具体是什么,下面......
  • uniapp实现虚拟列表(元素固定高度)
    一、应用场景当接口返回数据太多时,前端可使用虚拟列表,实现长列表。二、原理只有在屏幕部分元素被显示出来,并且被更新,始终只有固定数量的节点,不会卡顿。三、效果图四、思路步骤使用Object.freeze冻结对象,极大优化性能生成多个元素的options,或者动态获取根据onPag......
  • python-字典的学习
    '''在Python中,字典字是一系列键—值对值。每个键都与一个值相关联,你可以使用键来访问与之相关联的值。与键相关联的值可以是数字、字符串、列表乃至字典。事实上,可将任何Python对象用作字典中的值。在Python中,字典用放在花括号{}中的一系列键—值对表示'''customer={'name......
  • 模板函数使用类型推导时的bug
    templatestaticboolparse_a_value(T&val,Json::Valuejson_val){if(json_val.isNull())returnfalse;if(typeid(val)==typeid(int)||typeid(val)==typeid(int16_t)||typeid(val)==typeid(int8_t)||typeid(val)==typeid(int32_t)){......