py005_python文件、异常、模块和包

1. 文件介绍

  • **概述:**文件就是存储在磁盘上的,可以重复使用的数据或者功能集合。

    • 将数据存储到磁盘中时,都会以文件为单位保存,叫做数据的持久化。
    • 在内存中存储的数据,是以二进制形式存储在内存中的,不是文件。
  • 文件操作的步骤:

    • 文件操作主要分为读取和写入两类,基本步骤都包含打开文件、操作数据和关闭文件。

    • 读取文件

      • 打开文件
      • 读取数据
      • 关闭文件
    • 写入文件

      • 打开文件
      • 写入数据
      • 关闭文件

2. 文件的读取

  • 文件打开:

    • 使用open()函数打开文件,该函数返回一个file对象。

    • 格式:

      open(文件路径, 读写模式, 指定编码集)
      
    • 读写模式:

      • r:只读模式,若文件不存在会报错。
      • w:只写模式,打开文件时会清空原有内容,若文件不存在则会创建新文件。
      • a:追加模式,文件不会被清空,会在文件末尾追加数据,若文件不存在则会创建新文件。
    • 在 Windows 系统下,如果不指定编码集,默认使用 gbk 格式编码。

  • 文件读取:

    • 文件对象.read(n)
      • 可以指定最大读写字符数,不写n表示读取全部内容。
      • 如果连续使用read读取数据,将会在前一次读取数据的结尾位置继续读取,直到全部读完后返回空字符串。
      • 如果关闭文件后再打开,会重新开始从头读取。
    • 文件对象.readline():读取一行数据,以\n为读取终点,若没有更多数据则返回空字符串。
    • 文件对象.readlines():可以一次性读取全部数据,将数据以行为单位进行分割,生成一个列表。
  • **文件关闭:**格式:文件对象.close(),文件关闭后不能继续操作文件。

  • 代码示例:

    file = open('./data/1.txt', 'r', encoding='utf-8')
    # 读取全部内容
    # content = file.read()
    # print(content)
    # 读取最多3个字符的内容
    # content = file.read(3)
    # print(content)
    # content = file.read(3)
    # print(content)
    
    # 读取一行数据
    content = file.readline()
    print(content)
    content = file.readline()
    print(content)
    # 一次性读取全部数据,将数据以行为单位进行分割,生成一个列表
    content = file.readlines()
    print(content)
    file.close()
    

3. 文件的写入

  • 文件打开:

    • 使用open()函数打开文件,该函数返回一个file对象。

    • 格式:

      open(文件路径, 读写模式, 指定编码集)
      
  • 文件写入:

    • 文件对象.write(要写入的内容):将指定内容写入文件。
    • 文件对象.writelines():可将一个包含多行内容的列表写入文件。
  • **文件关闭:**格式:文件对象.close(),文件关闭后不能继续操作文件。

  • 代码示例:

    file = open('./data/2.txt', 'w', encoding='utf-8')
    file.write("这是要写入的内容。\n")
    lines = ["第一行\n", "第二行\n", "第三行\n"]
    file.writelines(lines)
    

4. 文件的追加

  • 代码示例:

    file = open('./data/2.txt', 'a', encoding='utf-8')
    file.write("追加的内容。\n")
    

5. 文件的读写模式

  • r:读取模式

    • r:文本型读取模式
    • rb:字节型读取模式
    • r+:文本型读取模式加强,可读写
    • rb+:字节型读取模式加强,可读写
  • w:写入模式

    • w:文本型写入模式

    • wb:字节型写入模式

    • w+:文本型写入模式加强,可读写

    • wb+:字节型写入模式加强,可读写

  • a:追加模式

    • a:文本型追加模式
    • ab:字节型追加模式
    • a+:文本型追加模式加强,可读写
    • ab+:字节型追加模式加强,可读写

6. 异常

  • **概述:**异常就是代码在执行的过程中出现的错误,会造成程序的终止(Error)。

    • 异常:程序运行过程中出现的错误,会造成程序的终止运行。
    • 警告:程序运行的结果可能和我们预想的不一致,不一定会造成程序的终止。
    • 程序从上到下依次运行,当执行到某一行代码出现异常后,会立即终止程序,无法继续执行。
  • 常见的异常类型:

    • NameError
    • TypeError
    • ValueError
    • KeyError
    • IndexError
  • 异常捕获:

    • 在开发中,我们一般不希望异常造成程序崩溃,所以我们会使用try...except对异常进行捕获。

    • 格式:

      try:  # try必须配合except,不能单独使用
          可能出现异常的代码
      except:
          try 中的代码出现异常后将会执行此代码
      
    • 如果try中的代码没有出现 异常,则不会执行except中的代码。

    • 如果代码出现异常,程序不会崩溃,会执行except中的代码。

    • try中的代码会从上到下依次运行,当代码出现异常后,不会执行try中的后续代码,而是直接执行except中的代码。

  • 捕获指定类型的异常:

    • 概述:在出现异常时,最后一行信息中,冒号之前的是异常类型,冒号之后的是异常信息描述。

    • 格式:

      try:
          可能会出现异常的代码
      except 异常类型1:
          出现异常类型1执行的代码
      except 异常类型2:
          出现异常类型2执行的代码
      ...
      # 如果出现的异常不是我们指定的类型中的其中一个,则异常依然会造成程序终止
      
    • 程序中不可能同时出现多个异常,因为一个异常出现,程序就退出了。

  • 捕获异常描述信息:

    • 格式:

      try:
          可能会出现异常的代码
      except 异常类型 as 变量名:
          print(变量名)  # 此时会输出异常信息
      except 异常类型 as 变量名:
          print(变量名)  # 此时会输出异常信息
      
  • 异常中的else

    • 格式:

      try:
          可能出现异常的代码
      except:
          如果try中的代码出现了异常执行的代码
      else:
          如果try中的代码没有出现异常时执行的代码
      
  • 异常中的finally

    • 格式:

      try:
          可能出现异常的代码
      except:
          如果try中的代码出现了异常执行的代码
      else:
          如果try中的代码没有出现异常时执行的代码
      finally:
          无论是否出现异常都会执行的代码
      
  • 异常传递:

    • 存在异常嵌套的情况下,如果内层try没有捕获到异常,可以传递到外层进行捕获,如果外层还是没有捕获到将会继续向外传递,直到程序终止为止。
  • 代码示例:

    # print(a)  # NameError: name 'a' is not defined
    # print(1 + 'a')  # TypeError: unsupported operand type(s) for +: 'int' and 'str'
    # dict1 = {}
    # print(dict1['name'])  # KeyError: 'name'
    
    try:
        print(2 / 1)  # 会被执行
        print(1 / 0)  # 出现异常,直接去执行except中的代码
        print(1 / 2)  # 不会被执行
    except ZeroDivisionError:
        print("0不能作为除数存在")
    
    try:
        print(a)  # NameError
        print(1 + '2')  # TypeError
    except NameError:
        print("NameError:出现了变量未定义错误")
    except TypeError:
        print("TypeError:出现了类型不一致错误")
    except Exception:
        print("出现了未知异常")
    
    try:
        print(1 / 0)
        print(a)  # NameError
        print(1 + '2')  # TypeError
    except (NameError, TypeError):
        print("出现了NameError或者TypeError")
    except Exception as error:
        print(f"出现了未知异常,{error}")
    
    try:
        print(a)  # NameError
        print(1 + '2')  # TypeError
    except NameError as error:
        print(error)
    except TypeError as error:
        print(error)
    except Exception as error:
        print(error)
    
    try:
        print(1 / 0)
    except:
        print("出现异常时执行")
    else:
        print("未出现异常时执行")
    
    try:
        print(1 / 0)
        print(1 / 2)
    except:
        print("出现异常时执行")
    else:
        print("未出现异常时执行")
    finally:
        print("无论是否出现异常都会执行")
    
    try:
        print('外层异常')
        try:
            print('内层异常')
            print(1 + '2')
        except NameError:
            print('变量没有被定义')
    except TypeError:
        print('数据类型错误')
    

7. 模块

  • **概述:**别人或自己已经写好的功能或者代码,可以通过导入模块的手段进行调用。

  • 作用:

    • 增加代码的复用率,同一个模块中的功能可以在不同文件或工程中使用 。
    • 通过简单的调用实现复杂的功能,降低开发门槛。
    • 是多人协同开发的基础。
  • 导入方式:

    • 全部导入:一次性将模块中所有可以被导入的功能全部导入进去。
      • 导入格式:import 模块名称
      • 调用格式:模块名称.功能名
    • 局部导入:
      • 导入格式:from 模块名 import 功能名
      • 调用格式:功能名
      • 这种方式只能使用导入的功能,未导入的功能不能使用。
    • 局部导入:
      • 导入格式:from 模块名 import *
      • 调用格式:功能名
      • 这种方式还是属于局部导入,因为被导入的功能我们可以手动控制。
  • 给模块或功能起别名:

    • 概述:导入模块或者功能时,有些模块名称过长,或者功能层级过多,可以起别名,简化调用过程。
    • 给模块起别名:import 模块 as 别名
    • 给功能起别名:from 模块 import 功能名 as 别名
    • 起别名后在当前文件中只能使用别名,原名称失效。
  • 自定义模块:

    • 自己写的.py文件,在导入其他文件内部时,可以直接使用该文件中的功能,这个就是自定义模块。
    • 模块名称必须符合标识符命名规则。
  • __all__变量:

    • 在模块中可以在模块开始位置,增加一个__all__变量。
    • 在这个变量中,存储一个列表,写入到列表中的功能名称,就可以使用from ... import *的形式进行一次性导入。
    • 如果我们不在模块中书写__all__,则使用from ... import *可以导入全部功能。
    • 如果我们在模块中书写__all__ = [],则使用from ... import *无法导入任何功能。
    • 如果我们在模块中书写__all__ = [功能1, 功能2],则仅可以使用from ... import *导入功能1和功能2
    • __all__的值不影响全部导入的方式。
    • __all__的值不影响局部导入中指定功能的方式。
  • 代码示例:

    # import random
    
    # 调用
    # print(random.randint(1, 10))
    # print(random.random())
    
    # from random import randint
    
    # print(randint(1, 100))
    # print(random())  # NameError: name 'random' is not defined. Did you forget to import 'random'?
    
    # from random import *
    #
    # print(randint(1, 100))
    # print(random())
    
    # import random as rd
    
    # print(rd.randint(1, 10))
    # print(random.randint(1, 10))  # NameError: name 'random' is not defined.
    
    # from random import randint as rdt
    # from random import randint as rdt, random as rd
    # print(rdt(1, 10))
    
    import my_module_01
    
    print(my_module_01.age)
    my_module_01.func1()
    my_module_01.func2()
    

8. 包

  • **概述:**包是一种管理 Python 模块命名空间的方式,采用目录形式组织模块。包目录下必须包含 __init__.py 文件(Python 3.3 之后不是必需的,但为了兼容性建议保留),该文件可以为空,也可包含包的初始化代码或定义 __all__ 变量。

  • 包的导入:

    • 导入整个包

      import 包名
      
      • 使用包中的模块时,需使用完整的模块路径:包名.模块名.功能名
    • 导入包中的模块

      from 包名 import 模块名
      
      • 使用模块中的功能时,直接使用 模块名.功能名
    • 导入包中模块的功能

      from 包名.模块名 import 功能名
      
      • 使用功能时,直接使用 功能名
  • __init__.py文件的作用:

    • 标识该目录是一个 Python 包。
    • 可以在 __init__.py 中编写初始化代码,当包被导入时,这些代码会被执行。
    • 可以在 __init__.py 中定义 __all__ 变量,控制使用 from 包名 import * 时导入的模块。
  • 代码示例:

    假设包名为 my_package,包含 module1.pymodule2.py 两个模块。

    my_package/__init__.py

    # 可在这里编写初始化代码
    __all__ = ['module1', 'module2']
    

    my_package/module1.py

    def func1():
        print("这是 module1 中的 func1 函数。")
    

    my_package/module2.py

    def func2():
        print("这是 module2 中的 func2 函数。")
    

    在主程序中使用:

    # 导入整个包
    import my_package
    my_package.module1.func1()
    
    # 导入包中的模块
    from my_package import module2
    module2.func2()
    
    # 导入包中模块的功能
    from my_package.module1 import func1
    func1()
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值