Python07_异常、模块与包

声明

文章是基于:

哔哩哔哩上的《黑马程序员python教程,8天python从入门到精通,学python看这套就够了》视频教程所做的学习笔记,仅为学习使用!!如有侵权,联系删除

目录

一、了解异常

二、异常的捕获方法

(一)捕获常规异常

(二)捕获指定异常

(三)捕获多个异常

(四)捕获异常并输出描述信息

(五)捕获所有异常

(六)异常else

(七)异常的finally

三、异常的传递

四、Python模块

(一)模块的导入方式

import 模块名

from 模块名 import 类、变量、方法等

from 模块名 import *

import 模块名 as 别名

from 模块名 import 功能名 as 别名

(二)自定义模块

(三)测试模块

(四)__all__变量

五、Python包

(一)新增包

(二)导入包

方式一:import导入包、模块

方式二:from作为前提导入包 / 模块,配合import使用

方式三:

六、安装第三方Python包

(一)pip安装

(二)pip的网络优化

(三)pycharm安装

七、NumPy

(一)导入NumPy

 (二)生成NumPy数组

(三)NumPy的算术运算

(四)Numpy中的N维数组

(五)广播

 (六)访问元素

八、综合案例


一、了解异常

  • 当检测到一个错误时,Python解释器就无法继续执行了,反而出现了一些错误的提示 -->> BUG

二、异常的捕获方法

  • 提前假设某处会出现异常,做好提前准备,当真的出现异常的时候,可以有后续手段

(一)捕获常规异常

  •  # 尝试以r模式打开文件,如果文件不存在,则以w方式打开
     try:
         f = open("linux.txt", "r", encoding = "UTF-8")
     except:
         print("出现异常了,因为文件不存在,改为w模式去打开,不存在则会创建")
         f = open("linux.txt", "w", encoding = "UTF-8")

(二)捕获指定异常

  • 如果尝试执行的代码的异常类型要捕获的异常类型不一致,则无法捕获异常

  • 一般try下方只放一行尝试执行的代码

  • as设置别名e是一个异常对象

(三)捕获多个异常

(四)捕获异常并输出描述信息

(五)捕获所有异常

(六)异常else

  • else表示的是如果没有异常要执行的代码

(七)异常的finally

  • finally表示的是无论是否异常都要执行的代码,例如关闭文件

elsefinally 是两个可选元素

三、异常的传递

  • 异常的传递性:当函数func01中发生异常, 并且没有捕获处理这个异常的时候, 异常会传递到函数func02, 当func02也没有捕获处理这个异常的时候main函数会捕获这个异常

  • 所有函数都没有捕获异常的时候, 程序就会报错

  • 利用异常具有传递性的特点, 当我们想要保证程序不会因为异常崩溃的时候, 就可以main函数中(最顶级的层级)设置异常捕获, 由于无论在整个程序哪里发生异常, 最终都会传递main函数, 这样就可以确保所有的异常都会被捕获

四、Python模块

  • 模块是一个 Python 文件,以 .py 结尾,模块能定义函数,类和变量,模块里也能包含可执行的代码

  • 我们可以认为一个模块就是一个工具包, 每一个工具包中都有各种不同的工具供我们使用进而实现各种不同的功能

  • 大白话:模块就是一个Python文件,里面有类、函数、变量等,我们可以拿过来用导入模块去使用

(一)模块的导入方式

常用的组合形式:

  • import 模块名

    •  # 使用import导入time模块使用sleep功能(函数) 
       import time # time.py
       ​
       print("开始")
       # 让程序睡眠1秒(阻塞)
       # 通过.确定层级关系,sleep功能是time模块内的,可以使用模块内的任意功能
       time.sleep()
       print("结束")
  • from 模块名 import 类、变量、方法等

    •  # 导入时间模块中的sleep方法
       # 只用模块中的sleep方法
       # 只使用特定的模块
       from time import sleep
       ​
       print("开始")
       sleep(1)
  • from 模块名 import *

    •  # 导入时间模块中的所有的方法
       from time import *
       ​
       print("开始")
       # 让程序睡眠1秒(阻塞)
       # 写法与直接import不同,只用写具体的方法名即可完成
       sleep(1)
       print("结束")

    from好像一个大前提,使用from导入模块后,import导入功能,函数名即可以直接使用其中的功能;

    impor好像是实际上地、实实在在的引入当前编辑的python文件,如果导入模块,就需要通过层级关系来确定要使用的功能

  • import 模块名 as 别名

  • from 模块名 import 功能名 as 别名

    •  # 模块别名
       import time as tt
       ​
       tt.sleep(2)
       print("hello")
    •  # 功能别名
       from time import sleep as sl
       sl(2)
       print("hello")

(二)自定义模块

  • 每个Python文件都可以作为一个模块,模块的名字就是文件的名字. 也就是说自定义模块名必须要符合标识符命名规则

  • 不同模块,同名的功能,如果都被导入,那么后导入会覆盖先导入

(三)测试模块

解决措施:

在my_module1.py模块中引入:

 def test(a + b):
     print(a + b)
 ​
 # 只在当前文件中调用该函数,其他导入的文件内不符合该条件,则不执行test函数调用
 # 两个_  __name__是内置变量
 # 当文件直接运行时,这个变量的名字就会自动标记为main,所以if语句为true
 if __name__ == '__main__':
     test(1, 2)
     
 # 当from导入模块时,变量名 ≠ main,就不会执行

(四)__all__变量

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

  • 不写这个变量,则可以全部使用

  • __all__只作用在这个“ * ”上,手动的指定名字使用功能是无法限制

五、Python包

  • 从物理上看,包就是一个文件夹,在该文件夹下包含了一个 _init_.py 文件,该文件夹可用于包含多个模块文件

  • __init__.py文件存在,就是一个,如果没有,就只是一个和普通的文件夹

  • 从逻辑上看包的本质依然是模块

  • 当我们的模块文件越来越多时,可以帮助我们管理这些模块, 包的作用就是包含多个模块

(一)新增包

(二)导入包

  • 方式一:import导入包、模块

    •  import my_package.my_module1
       import my_package.my_module2
       ​
       # 包中的my_module1模块的info_print1()方法
       my_package.my_module1.info_print1()
       # 包中的my_module1模块的info_print2()方法
       my_package.my_module2.info_print2()
  • 方式二:from作为前提导入包 / 模块,配合import使用

    •  from my_package import my_module1
       from my_package import my_module2
       my_module1.info_print1()
       my_module2.info_print2()
       ​
       or
       ​
       from my_package.my_module1 import info_print1()
       from my_package.my_module2 import info_print2()
       info_print1()
       info_print2()
  • 方式三:

    • 必须在__init__.py文件中添加`_all_ = []`,控制允许导入的模块列表

    • __all__针对的是 > ’ from ... import * ‘ <这种方式,对> ‘ import xxx ’ <这种具体模块导入方式无效

六、安装第三方Python包

  • 一个包,就是一堆同类型功能集合体

  • 在Python程序的生态中,有许多非常多的第三方包(非Python官方),可以极大的帮助我们提高开发效率,如:

    • 科学计算中常用的:numpy包

    • 数据分析中常用的:pandas包

    • 大数据计算中常用的:pyspark、apache-flink包

    • 图形可视化常用的:matplotlib、pyecharts

    • 人工智能常用的:tensorflow

  • 由于是第三方,所以Python没有内置,所以我们需要安装它们才可以导入使用

(一)pip安装

  • 命令提示符程序

  • pip install 包名称

(二)pip的网络优化

  • 由于pip是连接的国外的网站进行包的下载,所以有的时候会速度很慢

  • 我们可以通过如下命令,让其连接国内的网站进行包的安装:

    • pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 包名称

    • Simple Index 是清华大学提供的一个网站,可供pip程序下载第三方包

    (三)pycharm安装

七、NumPy

        在深度学习的实现中,经常出现数组和矩阵的计算。NumPy的数组类(numpy.array)中提供了很多便捷的方法,在实现深度学习时,我们将使用这些方法。

(一)导入NumPy

        NumPy是外部库,因此首先要导入NumPy库

import numpy as np # 将numpy作为np导入
                   # NumPy相关的方法均可通过np来调用

 (二)生成NumPy数组

        要生成NumPy数组,需要使用np.array()方法。np.array()接收Python列表作为参数,生成NumPy数组(numpy.ndarray)

x = np.array( [1.0, 2.0, 3.0] )
print(x) 

(三)NumPy的算术运算

x = np.array( [1.0, 2.0, 3.0] )
y = np.array( [2.0, 4.0, 6.0] )
# 对应元素加法
x + y # 3, 6, 9
# 对应元素减法
x - y # -1, -2, -3
# 对应元素乘法
x * y # 2, 8, 18
# 对应元素除法
x / y # 0.5, 0.5, 0.5

        需要注意的是,数组x和数组y的元素个数是相同的。当x和y的元素个数相同时,可以对各个元素进行运算。如果元素个数不同,程序就会报错,所以元素个数保持一致非常重要。

        NumPy数组不仅可以元素运算,也可以和单一的数值(标量)组合起来进行运算。此时,需要在NumPy数组的各个元素和标量之间进行运算。这个功能也被称为广播

x = np.appay( [1.0, 2.0, 3.0] )
x / 2.0 # array( [0.5, 1.0, 1.5] )

(四)Numpy中的N维数组

        NumPy不仅可以生成一维数组,也可以生成多维数组。比如,生成如下的二维数组(矩阵)

A = np.array( [1, 2], [3, 4] )
print(A) # [ [1, 2], [3, 4] ]

A.shape # 查看矩阵的形状 -->>(2, 2)

A.dtype # 查看矩阵元素的数据类型 -->> int64

       生成了一个2 x 2的矩阵A。和数组的算术运算一样, 矩阵同样可以算术运算,并且也可以在相同形状的矩阵间以对应元素的方式进行。

B = np.array( [3, 0]. [0, 6] )
A = np.array( [1, 2], [3, 4] )

A + B # [4, 2] , [3, 10]
A * B # [3, 0] , [0, 24] 

        并且,也可以通过标量(单一数值)对矩阵进行算术运算。这也是基于广播的功能

A * 10 # [10, 20], [30, 40]

        数学上将一维数组称为向量,将二维数组称为矩阵。另外,可以将一般化之后的向量 or 矩阵等统称为张量。

(五)广播

        NumPy中,形状不同的数组之间也可以进行运算。之前的例子中,在2×2的矩阵 A 和标量 10 之间进行了乘法运算。在这个过程中,如图所示,标量 10 被扩展成了2 × 2的形状,然后再与矩阵 A 进行乘法运算。这个功能称为广播。

A = np.array( [ [1, 2], [3, 4] ] )
B = np.array( [10, 20] )
A * B # 结果:[ 10, 40 ], [ 30, 80 ]

 一维数组 B 被变成了和二维数组 A 相同的形状,然后再以对应元素的方式进行运算。

 (六)访问元素

        元素的索引从0开始。对各个元素的访问可按如下方式进行。

X = np.array( [ [51, 55], [14, 19], [0, 4] ] )
X[0] # 第0行,[51, 55]
X[0][1] # (0, 1)的元素,55
        51        55
1419
04

        也可以用使用for语句访问各个元素

for row in X:
    print(row)

"""
[51 55]
[14 19]
[0 4]
"""

        还可以使用数组访问各个元素

X = X.flatten() # 将X扁平化,即转换为一维数组
print(X) # [51 55 14 19 0 4] 
X[ np.array( [0, 2, 4] ) ]  # 传入一个包含索引值的数组,选择X数组中对应索引位置的元素
                            # 通过传入数组[0, 2, 4],选择了X数组中索引为 0、2、4 的元素
                            # np.array 表示创建一个 NumPy 数组

        运用这个标记法,可以获取满足一定条件的元素。例如,要从 X 中抽出大于15的元素,可以写成如下形式。

X > 15 # array( [ True, True, False, True, False, False], dtype=bool )
X[ X > 15 ] # array( [51, 55, 19] )

        对NumPy数组使用不等号运算符等(上例中是 X > 15 ),结果会得到一个布尔型的数组。上例中就是使用这个布尔型数组取出了数组的各个元素(取出 True 对应的元素)。

八、综合案例

  •  str_util.py:
    • def str_reverse(s):
      	"""
      	功能是将字符串完成反转
      	:param s:将被反转的字符串
      	:return :反转后的字符串
      	"""
      	return s[::-1]
      
      def substr(s, x, y):
          """
          功能是按照给定的下标完成给定字符串的切片
          :param s:即被切片的字符串
          :param x:切片的开始下标
          :param y:切片的结束下标
          :return 切片完成后的字符串
          """
          return s[x:y]
      
      if __name__ == '__main__':
          print(str_reverse("黑马程序员"))
          print(substr("黑马程序员", 1, 3))
  •  file_util.py:
    • def print_file_info(file_name):
          """
          功能是:将给定路径的文件内容输出到控制台中
          :param file_name: 即将读取的文件路径
          :return: None
          """
          f = None
          try:
              f = open(file_name, "r", encoding="UTF-8")
              content = f.read()
              print("文件的全部内容如下:")
              print(content)
          except Exception as e:
              print(f"程序出现异常了,原因是:{e}")
          finally:
              if f: # if语句中None是False,若f是None说明文件读取异常,即文件不存在
                  f.close()
                  
      def append_to_file(file_name, data):
          """
          功能:将指定的数据追加到指定的文件中
          :param file_name:指定的文件路径
          :param data:指定的数据
          :return: None
          """
          f = open(file_name, "a", encoding="UTF-8")
          f.write(data)
          f.write("\n")
          f.close()
  •  主程序.py:
    • import my_utils.str_util
      from my_utils.file_util
      
      print(my_utils.str_util.str_reverse("黑暗面"))
      print(my_utils.str_utile.substr("itheima", 0, 4))
      
      file_util.print_file_info()
      file_util.append_to_file()
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Star_KeyW

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值