模块、包和异常

news2024/10/5 21:18:26

目录

  • 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_测试模块2

lz_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 CatModule

DogModule.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 setup

setup(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.gz
 cd 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 / num
    print(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 / num
    print(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
发现错误:密码长度不够

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/391299.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LPDDR4x 的 学习总结(4) - SDRAM chip的组织结构

上节总结cell的结构和基本操作 本节基于cell组合起来的DRAM组织结构 DDR Device 的组织结构 Cells 以特定的方式组成 Column/Row/Bank/Chip/Rank/DIMM/Channel等多层级组织结构如下图: 图1 - DRAM的组织结构 图2 - DRAM容量的组织结构图 Channel: 同1个DDR控制器 …

GIT基础常用命令-1 GIT基础篇

git基础常用命令-1 GIT基础篇1.git简介及配置1.1 git简介1.2 git配置config1.2.1 查看配置git config1.2.2 配置设置1.2.3 获取帮助git help2 GIT基础常用命令2.1 获取镜像仓库2.1.1 git init2.1.2 git clone2.2 本地仓库常用命令2.2.1 git status2.2.2 git add2.2.3 git diff2…

seata1.5.2使用从零快速上手(提供代码与安装包)

1.软件准备: 1.1 seata1.5.2 官网下载:地址:http://seata.io/zh-cn/ server源码:https://github.com/seata/seata 百度云下载(建议): 百度下载 链接:https://pan.baidu.com/s/1eilbSI0YdmupHYI7FroTsw 提取码&…

【编程基础之Python】10、Python中的运算符

【编程基础之Python】10、Python中的运算符Python中的运算符算术运算符赋值运算符比较运算符逻辑运算符位运算符成员运算符身份运算符运算符优先级运算符总结Python中的运算符 Python是一门非常流行的编程语言,它支持各种运算符来执行各种操作。这篇文章将详细介绍…

构造有向无环图(拓扑排序)

蓝桥杯集训每日一题 acwing3696 给定一个由 n 个点和 m 条边构成的图。 不保证给定的图是连通的。 图中的一部分边的方向已经确定,你不能改变它们的方向。 剩下的边还未确定方向,你需要为每一条还未确定方向的边指定方向。 你需要保证在确定所有边的…

独家揭秘:站外引流的十大技巧!

在今天的互联网时代,如何有效地引流已成为网站运营者面临的一个重要问题。 站外引流是指通过在其他网站或平台上建立链接或发布内容,将流量引导到自己的网站,提高自己网站的访问量。 本文将为大家揭秘站外引流的十大技巧,帮助大…

python项目搭建(上)

提示:惊觉相思不露,原来只因已入骨 文章目录前言软件的安装HTTP协议1.安装Django启动Django路由子表定义数据库创建数据库表过滤条件生成HTML前言 这里是用python搭建的一个**销售管理系统,用于记录个人遇到的一些错误 提示:以下…

软测入门(七)python操作数据文件(Json、yaml、csv、excel、xml)

python操作文件 txt文件 read() : 读取所有readline() : 读取一行readlines() : 读取所有,且以行为单位,放入list列表中 file open(r"F:\abc.txt", "r", encoding"utf-8") # 以utf-8格式读取文件 # 读取所有 # print…

IM即时通讯开发之常用加解密算法与通讯安全讲解

平时开发工作中,我们会经常接触加密、解密的技术。尤其在今天移动互联网时代,越来越多的用户会将数据存储在云端,或使用在线的服务处理信息。这些数据有些涉及用户的隐私,有些涉及用户的财产,要是没有一套的方案来解决…

儿童写作业的台灯怎么选择?2023给孩子买台灯最新推荐一下

儿童年龄比较小,所以眼睛也比较脆弱,然而现在的社会普遍节奏较快,无论是上班族,还是大中小学生,压力都比较大,儿童经常晚上看书、写字学习,眼睛难免劳累,所以儿童台灯最重要的就是柔…

CDGA|给金融科技数据治理的四大建议,从根基上解决问题

随着我国金融科技行业的发展,当前的数据治理水平已无法满足金融反哺实体经济发展的效率需要。 目前主要存在数据基础设施不完善导致的治理根基薄弱核心问题,建议从以下四个方面进行完善数据基础设施,构筑金融科技数据治理体系。 加强顶层设计…

Springboot整合RabbitMQ并使用

1、Springboot整合RabbitMQ 1、引入场景启动器 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId> </dependency>引入AMQP场景启动器之后&#xff0c;RabbitAutoConfiguratio…

变电站应用监控系统6大优势,你知道几个?

变电站是改变电压、控制和分配电能的场所&#xff0c;发展方向是自动化、数字化、网络化、智能化。 泛地缘科技针对电力行业用户的使用特点&#xff0c;利用电网现有的网络资源&#xff0c;推出集动力监控、环境监理、门禁系统、消防系统、视频监控于一身的物联网云盒监控系统。…

05-思维导图Xmind快速入门

文章目录5.1 认识思维导图5.2 Xmind的主要结构及主题元素5.2.1 Xmind的多种结构5.2.2 主题分类5.2.3 Xmind的主题元素章节总结5.1 认识思维导图 什么是思维导图&#xff1f; 思维导图是一种将思维进行可视化的实用工具。 具体实现方法是用一个关键词去引发相关想法&#xff0…

Hive实战 --- 电子商务消费行为分析

目录 数据结构 Customer表 Transaction表 Store表 Review表 上传数据 创建目录用于存放数据 把本地文件上传到HDFS上 创建外部表 创建数据库 创建表 数据清洗 对transaction_details中的重复数据生成新ID 过滤掉store_review中没有评分的数据 找出PII (personal …

位图/布隆过滤器/海量数据处理方式

位图 位图的概念 所谓位图&#xff0c;就是用每一位来存放某种状态&#xff0c;适用于海量数据&#xff0c;数据无重复的场景。通常是用来判断某个数据存不存在的。 直接来看问题&#xff1a; 给40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符号整数&#xff0…

Gradle+SpringBoot多模块开发

关于使用Gradle结合SpringBoot进行多模块开发。 本来是打算使用buildSrc之类的&#xff0c;但是感觉好像好麻烦&#xff0c;使用这种方法就可以实现&#xff0c;没必要采用其他的。 我不怎么会表述&#xff0c;可能写的跟粑粑一样&#xff0c;哈哈哈哈 这是我的项目地址。 存在…

Java速成篇-Day01笔记

提示&#xff1a;这里只记录我个人不熟悉的知识&#xff0c;并非所有内容 笔记目录课程&#xff1a;04-第一行代码① jshell② 对象.方法课程&#xff1a;05-第一份源码① Java开发程序的流程② 入口方法课程&#xff1a;06-常见问题-中文乱码① 乱码原因② 解决方法课程&#…

【基础算法】单链表的OJ练习(4) # 分割链表 # 回文链表 #

文章目录前言分割链表回文链表写在最后前言 本章的OJ练习相对前面的难度加大了&#xff0c;但是换汤不换药&#xff0c;还是围绕单链表的性质来出题的。我相信&#xff0c;能够过了前面的OJ练习&#xff0c;本章的OJ也是轻轻松松。 对于OJ练习(3)&#xff1a;-> 传送门 <…

华为OD机试题,用 Java 解【单词反转】问题

华为Od必看系列 华为OD机试 全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典使用说明 参加华为od机试,一定要注意不…