python高级(一)程序结构和异常处理

本文是Python高级编程系列的第一篇,主要介绍了程序结构,包括模块(Module)和包(Package),详细讲解了模块的导入、变量、加载过程以及分类。此外,还探讨了异常处理的概念,包括常见异常类型、异常处理语法和raise语句的使用。通过学习,读者将能更好地理解和组织Python代码,并掌握异常处理的技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言: python高级将用三篇文章来进行梳理:

(一)程序结构和异常处理

(二)迭代和生成器

(三)函数式编程

本篇文章学习的内容是第一篇,目录如下:

01 程序结构

1.1  模块Module

1)定义

python中的模块指的是 包含一系列数据、函数和类的文件,通常以.py结尾。

python程序结构示意图

2)作用

让一些相关的数据、函数和类更有逻辑地组织在一起,使逻辑结构更加清晰。

3)导入

python模块导入
importfrom import
语法

1) import 路径.模 块            2) import 路径.模块 as 别名  

1)from 路径.模块 import 成员名

2)from 路径.模块 import 成员名 as 别名

3)from 路径.模块 import *

作用将模块整体导入到当前模块中将模块内的成员导入到当前模块作用域中
使用模块名.成员名直接使用成员名

(1)python模块import & from import 导入示例:

(2)不同成员(函数、实例方法、类方法)导入实例:

4)模块变量

__doc__变量:文档字符串

__name__变量: 模块自身名字,可以判断是否为主模块

5)加载过程

模块导入时,所有的语句都会执行,如果一个模块已经执行,再次导入时不会重新执行该模块的语句。

(1) __doc__ 变量 实例:

a.数据、函数和类的三引号注释 都可以在 python 集成开发环境 IDE(integrated development environment)  pycharm中通过 __doc__ 查看

b. 也 可以查看 python的标准库文档说明

注:python的标准库 文档说明 (下面有提到)还可以 通过终端查看

如random是python的标准库之一

(2) __name__变量实例 :

A. __name__有两种输出方式

a. 在其他模块中输入print(__name__) ,并 在当前文件中导 入其模块名 , 打印结果是其他模块的真实模块名 ,如下图:

b.在当前文件中输入 print(__name__) ,直接打印的结果是__main__, 表示当前文件为主模块。

B.__name__的使用场景

在项目正式交付之前程序员会进行功能测试,如下图是学生管理信息系统的bbl( 业务逻辑层 )测试用例,用于测试当前模块代码是否有问题。但当项目交付给客户之后,客户会在main(入口)运行项目,这部分测试用例就不应该执行了。为了实现这个目的,需要在main模块加上 if __name__ == "__main__": , 表示在main模块中运行代码时才执行程序,如果当前模块不是主模块,则无需执行。 快捷键:main+回车

程序在main模块中运行时,上面的测试用例不执行:

注: 可以把模块分为两类,一个是主模块,另一个是被导入模块, 被导入模块才能生成pyc文件 (main是主模块,没有生成pyc文件), pyc可以让程序的运行速度更快。 所以程序从main运行会节省程序的运行速度,而不建议从另外三个功能模块运行程序。

python是解释型语言,但为了提高运行速度,使用了一种编译的方法。编译之后得到 pyc文件 ,存储了字节码(特定于Python的表现形式,不是机器码)。

6)分类

(1)内置模块(builtins),在解析器内部可以直接使用;

注:python的内置模块和 标准库模块可以在pycharm中使用 快捷键 ctrl+鼠标左键查看文档说明

如下python的标准库模块之一random的文档说明:

如下是python的内置模块之一print的文档说明:

(2)标准库模块,安装python时已安装且可直接使用;

time模块-datetime模块-random模块-pathlib模块-os模块-shutil模块-CSV模块-argparse模块-sys模块-json&pickle&shelve&xml模块-re模块-logging模块-hashlib模块

a. time模块知识:

import time
# 人类时间:2021年12月31日 17:10:49
#时间元组:(年、月、日、时、分、秒、星期、年的第几天、与夏令时的偏移量)
tuple_time = time.localtime()
print(tuple_time[6])#星期
print(tuple_time[-3])#星期
print(tuple_time[:3])#年月日
print(tuple_time[3:6])#时分秒
print(tuple_time)


#想要记录某个时刻优先使用时间戳 机器时间:从1970年元旦到现在经过的秒数
print(time.time())#1640942021.335922
#时间戳-->时间元组
#语法:时间元组 = time.localtime(时间戳)
print(time.localtime(1640942021.335922))
#时间元组-->时间戳
#语法:时间戳 = time.mktime(时间元组)
print(time.mktime(tuple_time))#1640942354.0




# 时间元组 <--> 字符串
#语法:字符串=time.strftime(时间格式,时间元组)
#21/12/31 17:31:04
print(time.strftime("%y/%m/%d %H:%M:%S",tuple_time))
#2021/12/31 17:31:04
print(time.strftime("%Y/%m/%d %H:%M:%S",tuple_time))
# 语法:时间元组 = time.strptime(字符串,时间格式)
print(time.strptime("2021/12/31 17:31:04","%Y/%m/%d %H:%M:%S"))
print(time.strptime("年份是:2021,月份是:09","年份是:%Y,月份是:%m"))

打印结果:

b. time模块实例:

"""
定义函数,根据年月日获取星期
输入:2022 1 3
输出:星期一
"""
import time
def get_week(year,month,day):
    str_time = "%s/%s/%s"%(year,month,day)
    print(str_time)
    tuple_time =time.strptime(str_time,"%Y/%m/%d")
    tuple_week = ("星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日")
    week_index=tuple_time[6]
    return tuple_week[week_index]
    # return tuple_time[6]


print(get_week(2022,1,3))

(3)第三方模块(通常为开源),需要自己安装;

(4)用户自己编写的模块(可以作为其他人的第三方模块)。

1.2 包 Package

1)定义

将模块以 文件夹的形式 进行分组管理。

(1) 以pycharm举例,主界面左侧的project最上面一层为项目的根目录,如果想要把作用域的范围缩小, 可以通过给主模块所在的文件夹 设置Mark Directory as -->Sources Root 来声明作用域。如下图:

通过为此类别分配文件夹,可以告诉IDE编译器此文件夹及其子文件夹包含应作为构建过程的一部分进行编译的源代码。

White-Legend

( 2)直接创建包 (包含__init__文件):

也可以先创建文件,然后在文件中新建 __init__文件

注:带init的是包(也是文件夹),不带init的只是文件夹,包的作用是可以通过init对整个包里的所有代码进行封装,当包里的文件很多时,可以提供部分常用文件的调用,更加方便。

2)作用

把一些相关的模块组织在一起,使逻辑结构更清晰。

3)导入

(1)主流做法(本篇文章开头的导入部分为主流做法)

1.在被导入模块写入成员(函数、实例方法、类)

2.在主模块进行导入

(2) 非主流做法

1.在被导入模块写入成员(函数、实例方法、类)

2.在被导入模块所在的包的__init__文件里进行配置(和主流做法的第2步相同)

3.在主模块进行导入(import或from 后面的内容只导入到包)

注:

非主流做法的适用于代码量、文件量比较庞大的时候,更常用的是主流做法。

非主流做法实例:

第一步:

第二步:(import 和from import 二选一)

第三步: (import 和from import 二选一)

2.1 异常

1)异常

(1) 定义

运行时检测到的错误。 错误通常分类两种 : 一类是 语法错误 ,这个是程序员自己需要调整的,必须在程序执行之前就改正,比如def dog后不加冒号;还有 一类是 逻辑错误 ,通常是由于数据超过有效范围引发的错误。

python解释器检测到错误, 触发异常 (也允许程序员自己触发异常)

程序员编写特定的代码,专门用来 捕捉 这个 异常 (这段代码与程序逻辑无关,与异常处理有关)

如果捕捉成功则进入另外一个处理分支,执行你为其定制的逻辑,使程序不会崩溃, 保证程序的健壮性与容错性 ,这就是 异常处理 。

战争热诚

(2) 常见语法错误

NameError名称异常:变量未定义;

TypeError类型异常:不同类型数据进行运算;

IndexError索引异常:超出索引范围;

AttributeError属性异常:对象没有对应名称的属性;

KeyError键异常:没有对应名称的键

Exception异常基类

......

NameError 实例:

2)异常处理

(1) 定义

将程序由异常状态转为正常流程。

(2)语法

try:
可能触发异常的语句
except 错误类型1 [as 变量1]:
处理语句1
except 错误类型2 [as 变量2]:
处理语句2
except Exception [as 变量3]:
不是以上错误类型的处理语句
else:
未发生异常的语句
finally:
无论是否发生异常的语句


"""
as子句用于绑定错误对象的变量,可以省略
except子句可以有一个或者多个,用来捕捉某种类型的错误
else子句最多只能有一个
finally子句最多只能有一个,如果没有except子句,必须存在
如果异常没有被捕捉到,会向上层(调用出)继续传递,直到程序终止运行
"""

异常处理实例(逻辑错误):

"""
异常处理:
适用性:不处理语法错误,而是针对逻辑错误
现象:程序遇到错误就会不断向上返回
价值:保障程序能够按照既定的流程执行
本质:错误的快速传递通道


"""
# 逻辑错误通常是由于数据超过有效范围引发的错误
# 处理方式1.包治百病(推荐使用)
def div_apple(apple_count):
    try:
        person_count = int(input('请输入人数:'))
        result = apple_count/person_count
        print('每人分%s个苹果'%result)
#     except Exception:
    except:
        print('程序出错了')
div_apple(10)
print('后续逻辑')


# 处理方式2.对症下药(官方建议)
def div_apple(apple_count):
    try:
        person_count = int(input('请输入人数:'))
        result = apple_count/person_count
        print('每人分%s个苹果'%result)
    except ValueError:
        print('错误,输入的不是整数')
    except ZeroDivisionError:
        print('错误,输入的是零')
div_apple(10)
print('后续逻辑')


# 处理方式3.无论是否发生异常,一定执行某些逻辑
def div_apple(apple_count):
    try:
        person_count = int(input('请输入人数:'))
        result = apple_count/person_count
        print('每人分%s个苹果'%result)
        #打开文件
        #操作文件
    finally:
        print('分苹果结束啦')
        #关闭文件
div_apple(10)
print('后续逻辑')




# 处理方式4.没有错误时才执行的逻辑
def div_apple(apple_count):
    try:
        person_count = int(input('请输入人数:'))
        result = apple_count/person_count
        print('每人分%s个苹果'%result)


    except Exception:
        print('程序出错啦')
    else:
        print('分苹果成功啦')


div_apple(10)
print('后续逻辑')

3)raise语句

(1)定义

抛出一个错误,让程序进入异常状态。

(2)作用

在程序调用比较深时,由主调函数传递错误信息要层层return比较麻烦,认为抛出异常,可以直接传递错误信息。

(3)语法

raise [Exception [, args [, traceback]]]
"""
语句中Exception是异常的类型(例如,NameError)
参数是一个异常参数值,该参数是可选的,如果不提供,异常的参数是"None"。
最后一个参数是可选的(在实践中很少使用)。
"""

(4)raise实例

"""
主动创造错误
raise   try
发送   接收
"""
def input_password():
    # 1.提示用户输入密码
    pwd = input('请输入密码:')


    # 2.判断密码长度,如果长度>=6,返回用户输入的密码
    if len(pwd) >= 6:
        return pwd


    # 3.密码长度不够,抛出异常
    raise Exception('密码长度不够')


while True:
    try:
        user_pwd = input_password()
        print(user_pwd)
        break
    except Exception as e:
        print(e.args)

参考资料:

[1] Python——模块(Module)和包(Package)

https://blog.youkuaiyun.com/qiqicos/article/details/79208039

[2] 常用的python标准库模块

https://www.cnblogs.com/xixi18/p/8406301.html

[3] Python内置模块与标准库

https://www.cnblogs.com/pluse/p/8667864.html

[4] Pycharm 中 Mark Directory As 里的 Sources Root 的作用

https://blog.youkuaiyun.com/u011318077/article/details/105507485

[5] Python异常及处理方法总结

https://blog.youkuaiyun.com/sinat_38682860/article/details/90705790

[6] python 一篇搞定所有的异常处理

https://www.cnblogs.com/wj-1314/p/8707804.html

花样早餐展位

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值