热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

模块、包和异常

目录

目录

  • 1.模块
    • import 导入
    • from...import 导入
  • 2. 模块的搜索顺序
  • 3. __name__属性的使用
  • 4. 包
    • 包的使用步骤
  • 5. 发布模块
  • 6. 安装模块
  • 7. 卸载模块
  • 8. pip 安装第三方模块
  • 9. 异常处理
    • 异常捕获
    • 异常的传递
    • 抛出 raise 异常


1.模块

模块是 Python 程序架构的一个核心概念

  • 每一个以扩展名 py 结尾的 Python 源代码文件都是一个 模块
  • 模块名 同样也是一个 标识符,需要符合标识符的命名规则
  • 在模块中定义的 全局变量 、函数、类 都是提供给外界直接使用的 工具
  • 模块 就好比是 工具包,要想使用这个工具包中的工具,就需要先 导入 这个模块

import 导入

import 模块名 是 一次性 把模块中 所有工具全部导入,并且通过 模块名/别名 访问

import 模块名1
import 模块名2

注意:在导入模块时,每个导入应该独占一行

导入之后 通过 模块名. 使用 模块提供的工具 —— 全局变量、函数、类。
如果模块名字太长还可以使用as 指定模块的别名, 例如:

import 模块名1 as 模块别名

from…import 导入

如果希望 从某一个模块 中,导入 部分 工具,就可以使用 from … import 的方式

# 从 模块 导入 某一个工具
from 模块名1 import 工具名

导入之后

  • 不需要 通过 模块名.调用
  • 可以直接使用 模块提供的工具 —— 全局变量、函数、类

注意:
如果 两个模块,存在 同名的函数,那么 后导入模块的函数,会 覆盖掉先导入的函数;
开发时 import 代码应该统一写在 代码的顶部,更容易及时发现冲突,一旦发现冲突,可以使用 as 关键字 给其中一个工具起一个别名;
不建议使用from…import *的方式导入某个模块的所有内容,因为函数重名并没有任何的提示,出现问题不好排查。

使用示例:
假设现在有2个模块, 分别是:
lz_01_测试模块1.py

# 全局变量
title = "模块1"# 函数
def say_hello():print("我是 %s" % title)# 类
class Dog(object):pass

lz_02_测试模块2.py

# 全局变量
title = "模块2"# 函数
def say_hello():print("我是 %s" % title)# 类
class Cat(object):pass

(1) import导包的使用方式如下:

import lz_01_测试模块1
import lz_02_测试模块2lz_01_测试模块1.say_hello()
lz_02_测试模块2.say_hello()dog = lz_01_测试模块1.Dog()
print(dog)cat = lz_02_测试模块2.Cat()
print(cat)

(2) import as导包的使用方式如下:

import lz_01_测试模块1 as DogModule
import lz_02_测试模块2 as CatModuleDogModule.say_hello()
CatModule.say_hello()dog = DogModule.Dog()
print(dog)cat = CatModule.Cat()
print(cat)

(3) from…import导包的使用方式如下:

from lz_01_测试模块1 import Dog
from lz_02_测试模块2 import say_hello# 直接使用导入后的方法
say_hello()# 直接使用导入后的类
wangcai = Dog()
print(wangcai)

2. 模块的搜索顺序

Python 的解释器在 导入模块 时,会:

  • 首先搜索 当前目录 指定模块名的文件,如果有就直接导入
  • 如果没有,再搜索 系统目录

在开发时,给文件起名,不要和 系统的模块文件 重名;
Python 中每一个模块都有一个内置属性 file 可以 查看模块 的 完整路径, 例如:
print(DogModule.file), 输出结果:
/Users/chenyousheng/workspace/python/Learn/day01/lz_01_测试模块1.py

如下是一个导入系统random模块的用法

import random# 生成一个 0~10 的数字
rand = random.randint(0, 10)print(rand)

假设当前目录下,存在一个 random.py 的文件,程序就无法正常执行了!
因为, Python 的解释器会优先 加载当前目录 下的 random.py 而不会加载 系统的 random 模块

3. __name__属性的使用

首先明确下模块的导入原则:

  • 一个 独立的 Python 文件 就是一个 模块
  • 在导入文件时,文件中 所有没有任何缩进的代码 都会被执行一遍!

假设某个模块内定义了一些测试代码, 不想让别人导入的时候被执行了,只允许在当前文件中直接执行,那么就可以用到__name__属性了.

__name__ 是 Python 的一个内置属性,记录着一个 字符串:

  • 如果 是被其他文件导入的,__name__ 就是 模块名
  • 如果 是当前执行的程序 __name__main

例如: lz_xiaoming_模块.py定义如下:

# 输出当前执行模块的名字
# 如果直接执行模块,__main__
print("当前模块名字:%s" % __name__)def say_hello():print("这里是测试逻辑...")if __name__ == "__main__":# 文件被导入时,能够直接执行的代码不需要被执行!print("小明写的测试代码")say_hello()

直接运行该模块,输出结果如下:

当前模块名字:__main__
小明写的测试代码
这里是测试逻辑...

然后在 test.py中导入模块使用

import lz_xiaoming_模块print("-" * 50)

输出结果如下:

当前模块名字:lz_xiaoming_模块
--------------------------------------------------

可以看到, 导入后运行,输出的结果和直接执行的结果是不一样的.

4. 包

包 是一个 包含多个模块 的 特殊目录,目录下有一个 特殊的文件 init.py,包名的 命名方式和变量名一致,小写字母 + _,使用 import 包名 可以一次性导入 包 中 所有的模块

包的使用步骤


  • 新建一个 lz_message 的 包
  • 在目录下,新建两个文件 send_message.py 和 receive_message.py
  • 在 send_message 文件中定义一个 send 函数
  • 在 receive_message 文件中定义一个 receive 函数
  • 创建__init__.py声明对外导出的模块列表
  • 在外部直接导入 lz_message 的包使用

目录结构如下:
在这里插入图片描述
send_message.py和receive_message.py定义如下:

# send_message.py
def send(text):print("正在发送 %s..." % text)# receive_message.py def receive():return "这是来自 100xx 的短信"

__init__.py定义如下:

from . import send_message
from . import receive_message

使用方式如下:

# 导入包
import lz_message# 使用 包名.模块名.调用模块的方法
lz_message.send_message.send("hello")
txt = lz_message.receive_message.receive()
print(txt)

输出结果:

正在发送 hello...
这是来自 100xx 的短信

5. 发布模块

如果希望自己开发的模块,分享 给其他人,可以按照以下步骤操作
以发布上面创建的lz_message包为例

(1) 创建 setup.py
首先需要在模块外创建setup.py文件,内容如下:

from distutils.core import setupsetup(name="lz_message", # 包名version="1.0", # 版本description="lz's 发送和接收消息模块", # 描述信息long_description="完整的发送和接收消息模块", # 完整描述信息author="mchenys", # 作者author_email="mchenys@gmail.com", # 作者邮箱url="lz.com", # 主页py_modules=["lz_message.send_message","lz_message.receive_message"])

有关字典参数的详细信息,可以参阅官方网站:

(2) 构建模块
在控制台中切换到setup文件同级目录,我这里是pycharm项目的根目录,控制台输入如下命令:

python3 setup.py build

执行结果如下:
在这里插入图片描述
成功后会在当前目录下生成build目录
在这里插入图片描述

(3) 生成发布压缩包

控制台执行如下命令:

python3 setup.py sdist

执行结果如下:

在这里插入图片描述

此时根目录下会生成一个dist目录,里面有一个lz_message-1.0.tar.gz的压缩包
在这里插入图片描述

6. 安装模块

当你从别人那里得到一个已发布的模块压缩包后,我们就可以安装到python的内置目录内, 以上面发布的lz_message-1.0.tar.gz为例, 安装步骤如下:
假设我已经把lz_message-1.0.tar.gz复制到了桌面,那么需要在控制台上切换到~/Desktop目录

tar -zxvf lz_message-1.0.tar.gzcd lz_message-1.0 sudo python3 setup.py install

执行结果如下:
在这里插入图片描述
可以看到安装的模块被导入到/opt/homebrew/lib/python3.9/site-packages目录内, 进入该目录也可以查看到新安装的模块
在这里插入图片描述
模块安装完后, 就可以直接在import来使用了.
在这里插入图片描述

7. 卸载模块

直接从安装目录下,把安装模块的 目录 删除就可以

cd /opt/homebrew/lib/python3.9/site-packages
sudo rm -r lz_message*

8. pip 安装第三方模块

pip 是一个通用的 Python 包管理工具,提供了对 Python 包的查找、下载、安装、卸载等功能
例如针对pygame 模块的安装和卸载命令如下:

# 将模块安装到 Python 2.x 环境
$ sudo pip install pygame
$ sudo pip uninstall pygame# 将模块安装到 Python 3.x 环境
$ sudo pip3 install pygame
$ sudo pip3 uninstall pygame

安装效果:
在这里插入图片描述

如果在mac上提示sudo: pip: command not found, 按如下步骤进行安装:

  • curl https://bootstrap.pypa.io/pip/2.7/get-pip.py -o get-pip.py
  • sudo python get-pip.py
  • sudo easy_install pip

安装后通过pip --version 可以查看版本及安装目录

9. 异常处理

程序在运行时,如果 Python 解释器 遇到 到一个错误,会停止程序的执行,并且提示一些错误信息,这就是 异常。
程序停止执行并且提示错误信息 这个动作,我们通常称之为:抛出(raise)异常。

异常捕获

(1) 基本语法
如果 对某些代码的执行不能确定是否正确,可以增加 try(尝试) 来捕获异常, 语法格式如下:

try:尝试执行的代码
except:出现错误的处理

用法示例:

try:# 提示用户输入一个数字num = int(input("请输入数字:"))
except:print("请输入正确的数字")

(2) 错误类型捕获
在程序执行时,可能会遇到 不同类型的异常,并且需要 针对不同类型的异常,做出不同的响应,这个时候,就需要捕获错误类型了,语法如下:

try:# 尝试执行的代码pass
except 错误类型1:# 针对错误类型1,对应的代码处理pass
except (错误类型2, 错误类型3):# 针对错误类型2 和 3,对应的代码处理pass
except Exception as result:print("未知错误 %s" % result)

用法示例:

try:num = int(input("请输入整数:"))result = 8 / numprint(result)
except ValueError:print("请输入正确的整数")
except ZeroDivisionError:print("除 0 错误")

(3) 捕获未知错误
在开发时,要预判到所有可能出现的错误,还是有一定难度的,如果希望程序 无论出现任何错误,都不会因为 Python 解释器 抛出异常而被终止,可以再增加一个 except, 例如:

except Exception as result:print("未知错误 %s" % result)

(4) 异常捕获完整语法
在实际开发中,为了能够处理复杂的异常情况,完整的异常语法如下:

try:# 尝试执行的代码pass
except 错误类型1:# 针对错误类型1,对应的代码处理pass
except 错误类型2:# 针对错误类型2,对应的代码处理pass
except (错误类型3, 错误类型4):# 针对错误类型3 和 4,对应的代码处理pass
except Exception as result:# 打印错误信息print(result)
else:# 没有异常才会执行的代码pass
finally:# 无论是否有异常,都会执行的代码print("无论是否有异常,都会执行的代码")

  • else 只有在没有异常时才会执行的代码
  • finally 无论是否有异常,都会执行的代码

用法示例:

try:num = int(input("请输入整数:"))result = 8 / numprint(result)
except ValueError:print("请输入正确的整数")
except ZeroDivisionError:print("除 0 错误")
except Exception as result:print("未知错误 %s" % result)
else:print("正常执行")
finally:print("执行完成,但是不保证正确")

异常的传递


  • 异常的传递 —— 当 函数/方法 执行 出现异常,会 将异常传递 给 函数/方法 的 调用一方
  • 如果 传递到主程序,仍然 没有异常处理,程序才会被终止

def demo1():return int(input("请输入一个整数:"))def demo2():return demo1()try:print(demo2())
except ValueError:print("请输入正确的整数")
except Exception as result:print("未知错误 %s" % result)

输出结果:

请输入一个整数:aaa
请输入正确的整数

抛出 raise 异常

在开发中,除了 代码执行出错 Python 解释器会 抛出 异常之外,还可以根据 应用程序 特有的业务需求 主动抛出异常。
Python 中提供了一个 Exception 异常类,在开发时,如果满足 特定业务需求时,希望抛出异常,可以这样处理:

  • 创建 一个 Exception 的 对象
  • 使用 raise 关键字 抛出 异常对象
    用法示例:

def input_password():# 1. 提示用户输入密码pwd = input("请输入密码:")# 2. 判断密码长度,如果长度 >= 8,返回用户输入的密码if len(pwd) >= 8:return pwd# 3. 密码长度不够,需要抛出异常# 使用异常的错误信息字符串作为参数raise Exception("密码长度不够")try:user_pwd = input_password()print(user_pwd)
except Exception as result:print("发现错误:%s" % result)

输出结果:

请输入密码:aaa
发现错误:密码长度不够

可以看到捕获的异常结果就是抛出异常的字符串内容。


推荐阅读
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • 安装mysqlclient失败解决办法
    本文介绍了在MAC系统中,使用django使用mysql数据库报错的解决办法。通过源码安装mysqlclient或将mysql_config添加到系统环境变量中,可以解决安装mysqlclient失败的问题。同时,还介绍了查看mysql安装路径和使配置文件生效的方法。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 第四章高阶函数(参数传递、高阶函数、lambda表达式)(python进阶)的讲解和应用
    本文主要讲解了第四章高阶函数(参数传递、高阶函数、lambda表达式)的相关知识,包括函数参数传递机制和赋值机制、引用传递的概念和应用、默认参数的定义和使用等内容。同时介绍了高阶函数和lambda表达式的概念,并给出了一些实例代码进行演示。对于想要进一步提升python编程能力的读者来说,本文将是一个不错的学习资料。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • 31.项目部署
    目录1一些概念1.1项目部署1.2WSGI1.3uWSGI1.4Nginx2安装环境与迁移项目2.1项目内容2.2项目配置2.2.1DEBUG2.2.2STAT ... [详细]
  • 树莓派语音控制的配置方法和步骤
    本文介绍了在树莓派上实现语音控制的配置方法和步骤。首先感谢博主Eoman的帮助,文章参考了他的内容。树莓派的配置需要通过sudo raspi-config进行,然后使用Eoman的控制方法,即安装wiringPi库并编写控制引脚的脚本。具体的安装步骤和脚本编写方法在文章中详细介绍。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • 本文介绍了在Python中使用zlib模块进行字符串的压缩与解压缩的方法,并探讨了其在内存优化方面的应用。通过压缩存储URL等长字符串,可以大大降低内存消耗,虽然处理时间会增加,但是整体效果显著。同时,给出了参考链接,供进一步学习和应用。 ... [详细]
  • 开源Keras Faster RCNN模型介绍及代码结构解析
    本文介绍了开源Keras Faster RCNN模型的环境需求和代码结构,包括FasterRCNN源码解析、RPN与classifier定义、data_generators.py文件的功能以及损失计算。同时提供了该模型的开源地址和安装所需的库。 ... [详细]
  • Python使用Pillow包生成验证码图片的方法
    本文介绍了使用Python中的Pillow包生成验证码图片的方法。通过随机生成数字和符号,并添加干扰象素,生成一幅验证码图片。需要配置好Python环境,并安装Pillow库。代码实现包括导入Pillow包和随机模块,定义随机生成字母、数字和字体颜色的函数。 ... [详细]
  • 本文介绍了H5游戏性能优化和调试技巧,包括从问题表象出发进行优化、排除外部问题导致的卡顿、帧率设定、减少drawcall的方法、UI优化和图集渲染等八个理念。对于游戏程序员来说,解决游戏性能问题是一个关键的任务,本文提供了一些有用的参考价值。摘要长度为183字。 ... [详细]
  • Windows7企业版怎样存储安全新功能详解
    本文介绍了电脑公司发布的GHOST WIN7 SP1 X64 通用特别版 V2019.12,软件大小为5.71 GB,支持简体中文,属于国产软件,免费使用。文章还提到了用户评分和软件分类为Win7系统,运行环境为Windows。同时,文章还介绍了平台检测结果,无插件,通过了360、腾讯、金山和瑞星的检测。此外,文章还提到了本地下载文件大小为5.71 GB,需要先下载高速下载器才能进行高速下载。最后,文章详细解释了Windows7企业版的存储安全新功能。 ... [详细]
author-avatar
GloryWumie
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有