python的包和模块day12

发布于:2025-03-27 ⋅ 阅读:(26) ⋅ 点赞:(0)

2.4 __init__.py文件

__init__.py 的作用

  1. 标识包:

    • __init__.py 文件的存在标志着该目录是一个 Python 包。

    • 如果没有 __init__.py 文件,Python 会将目录视为普通目录,无法通过包的方式导入其中的模块。

  2. 初始化包:

    • 当包或包中的模块被导入时,__init__.py 文件中的代码会自动执行。

    • 可以在这里编写包的初始化逻辑,例如设置包级别的变量、导入子模块或执行其他初始化操作。

  3. 定义包的接口:

    • 可以在 __init__.py 中定义 __all__ 变量,明确指定通过 from package import * 导入时哪些模块或对象是公开的。

    • 也可以在 __init__.py 中导入包内的模块或子包,简化用户的导入方式。

  4. 命名空间管理:

    • __init__.py 文件可以帮助管理包的命名空间,确保包内的模块和子包能够正确导入和使用。

__all__ 的作用

  1. 控制 from module import \* 的行为:

    • 默认情况下,from module import * 会导入模块中所有不以 _ 开头的对象。

    • 如果定义了 __all__,则只有 __all__ 中列出的对象会被导入。

  2. 明确公开接口:

    • 通过 __all__,开发者可以明确告诉用户哪些对象是模块或包的公开接口,哪些是内部实现细节。

    • 这是一种良好的编程实践,有助于提高代码的可维护性和可读性。

  3. 防止意外导入:

    • 如果没有 __all__from module import * 可能会导入一些不希望暴露的内部对象。

    • 通过 __all__,可以避免这种情况。

示例1:在 __init__.py 中定义变量

可以在 __init__.py 中定义包级别的变量

# 包级别
import python.tx.gong_cheng as gc
print(gc.version)

#在__init__导入包其他模块的功能
from python.tx.gong_cheng import game2
game2()

 

2.5 模块与包的区别

模块
一个Python文件 一个包含__init__.py的文件夹
提供基本功能单元 用于组织多个模块
文件名为.py 目录名

Python异常

  • 作用

    用作信号通知,通知上层调用者有错误产生需要处理

1. try 语句

  • 语法

try:
    可能发生异常的语句块
except 错误类型1 [as 变量名1]:
    异常处理语句块1
except 错误类型2 [as 变量名2]:
    异常处理语句块2
...
except 错误类型n [as 变量名n]:
    异常处理语句块n
except:
    异常处理语句块other
else:
    未发生异常的语句
finally:
    最终的处理语句 

  • 作用

    尝试捕获异常,得到异常通知,将程序由异常状态变为正常状态

  • 说明

    except 子句可以有 1个或多个

    except: 不给错误类型,可以匹配全部的错误类型

    else 子句里的语句会在 没有错误发生时执行,当处于异常时不执行

    finally 子句里的语句,无论何时都执行

def change_Int():
    try:
        x = int(input("请输入一个整数:"))
        print('x=', x)
    except ValueError:
        print('您的输入不能转成整数')

    print("程序结束")

change_Int()

 

2. raise 语句

# 写一个函数, get_score 函数,读取用户输入的整数成绩,
# 成绩的正常值是0~100 之间, 要求, 如果不在0~100 之间
# 报 ValueError类型的错误

def get_score():
    x = int(input('请输入成绩'))
    if 0 <= x <= 100:
        print(f'你输入的成绩为{x}')
    else:
        raise ValueError

get_score()

 

 

  • 作用

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

    • 发送错误通知给调用者

    • 写一个程序,输入一个整数n,如果n不是整数则抛异常,如果n=0抛异常,否则计算result=10 / n,并输出结果,最后打印'程序运行完毕'

    • try:
          print('请输入除数')
          num = int(input())
          result = 10/num
      except ValueError:
          print('你输入的不是整数')
      except ZeroDivisionError:
          print('你输入的除数为0')
      else:
          print(result)
      finally:
          print('结束')

      练习,尽量完善所有功能,调试所有bug,可以用所学try处理异常。

    • ## 写一个函数, get_score 函数,读取用户输入的整数成绩,
      ## 成绩的正常值是0~100 之间, 要求, 如果不在0~100 之间
      ## 报 ValueError类型的错误

def game_run():
    import random
    count = 0
    conputer_num = random.randint(0,200)
    print('如果你想提前结束请输入201')
    while True:
        try:
            player_num = int(input('请输入你要猜的数字'))
        except ValueError as e:
            print('输入错误,请输入整数',e)
        else:
            count += 1
            if player_num == 201:
                print('-'*50)
                print('你选择提前结束')
                return
            elif player_num == conputer_num:
                print(f'恭喜你猜对了,你一共猜了{count}次')
                print('_'*50)
                break
            elif player_num < conputer_num:
                print('你猜小了')
            elif player_num > conputer_num:
                print('你猜大了')
            else:
                print('输入错误')
                break
        finally:
            pass

def game_menu():
    print('猜数字游戏要求电脑随机产生一个0-200的随机数')
    print('如果玩家猜大了,提示猜大了,反之亦然')
    print('按s开始游戏,按q退出游戏')


def game_exe():
    while True:
        game_menu()
        key = input('请输入你要执行的操作')
        if key == 'q':
            print('退出游戏')
            return
        elif key == 's':
                game_run()
        else:
            print('输入错误请重新输入')
            print('_'*50)

if __name__ == '__main__':
    game_exe()

 

3.Python全部的错误类型

错误类型 说明
ZeroDivisionError 除(或取模)零 (所有数据类型)
ValueError 传入无效的参数
AssertionError 断言语句失败
StopIteration 迭代器没有更多的值
IndexError 序列中没有此索引(index)
IndentationError 缩进错误
OSError 输入/输出操作失败
ImportError 导入模块/对象失败
NameError 未声明/初始化对象 (没有属性)
AttributeError 对象没有这个属性
<!-- 以下不常用 -->
GeneratorExit 生成器(generator)发生异常来通知退出
TypeError 对类型无效的操作
KeyboardInterrupt 用户中断执行(通常是输入^C)
OverflowError 数值运算超出最大限制
FloatingPointError 浮点计算错误
BaseException 所有异常的基类
SystemExit 解释器请求退出
Exception 常规错误的基类
StandardError 所有的内建标准异常的基类
ArithmeticError 所有数值计算错误的基类
EOFError 没有内建输入,到达EOF 标记
EnvironmentError 操作系统错误的基类
WindowsError 系统调用失败
LookupError 无效数据查询的基类
KeyError 映射中没有这个键
MemoryError 内存溢出错误(对于Python 解释器不是致命的)
UnboundLocalError 访问未初始化的本地变量
ReferenceError 弱引用(Weak reference)试图访问已经垃圾回收了的对象
RuntimeError 一般的运行时错误
NotImplementedError 尚未实现的方法
SyntaxError Python 语法错误
TabError Tab 和空格混用
SystemError 一般的解释器系统错误
UnicodeError Unicode 相关的错误
UnicodeDecodeError Unicode 解码时的错误
UnicodeEncodeError Unicode 编码时错误
UnicodeTranslateError Unicode 转换时错误
以下为警告类型
Warning 警告的基类
DeprecationWarning 关于被弃用的特征的警告
FutureWarning 关于构造将来语义会有改变的警告
OverflowWarning 旧的关于自动提升为长整型(long)的警告
PendingDeprecationWarning 关于特性将会被废弃的警告
RuntimeWarning 可疑的运行时行为(runtime behavior)的警告
SyntaxWarning 可疑的语法的警告
UserWarning 用户代码生成的警告

     练习2.

     写一个函数 get_age() 用来获取一个人的年龄信息
    此函数规定用户只能输入1~140之间的整数,如果用户输入其它的数则直接触发ValueError类型的错误! 

def get_age():
    print('请输入1~140的整数')
    try:
        age = int(input())
        if age < 0 or age > 140:
            raise ValueError('你输入的数字不在范围内')
    except ValueError as e:
        print('请输入有效整数', e)

    finally:
        pass
get_age()

 #也可以通过if语句自己定义错误类型。

文件操作是Python中常见的任务之一,用于创建、读取、写入和管理文件。以下是一些常见的文件操作任务的思路、总结和示例代码:

Python文件操作

文件操作是Python中常见的任务之一,用于创建、读取、写入和管理文件。以下是一些常见的文件操作任务的思路、总结和示例代码:

1. 打开文件

要执行文件操作,首先需要打开文件。使用open()函数可以打开文件,指定文件名以及打开模式(读取、写入、追加等)。

2. 读取文件

一旦文件被打开,可以使用不同的方法来读取文件内容。

# 打开一个文本文件以读取内容
file = open("example.txt", "r")
# 读取整个文件内容
content = file.read()

# 逐行读取文件内容
for line in file:  #直接遍历文件对象,每次读取一行。这种方式更内存友好,因为不需要将所有行读入内存。
    print(line)

3. 写入文件

要写入文件,需要打开文件以写入模式('w'),然后使用write()方法。

# 打开文件以写入内容
file = open("example.txt", "w")

# 写入内容
file.write("这是一个示例文本。")

4. 关闭文件

完成文件操作后,应该关闭文件,以释放资源和确保文件的完整性。

file.close()

5. 使用with

更安全的方法是使用with语句,它会自动关闭文件。

with open("example.txt", "r") as file:
    content = file.read()
    # 文件自动关闭

6. 检查是否存在

可以使用os.path.exists()来检查文件是否存在。

import os
if os.path.exists("example.txt"):
    print("文件存在")

练习题 

棒球比赛

你现在是一场采用特殊赛制棒球比赛的记录员。这场比赛由若干回合组成,过去几回合的得分可能会影响以后几回合的得分。

比赛开始时,记录是空白的。你会得到一个记录操作的字符串列表 ops,其中 ops[i] 是你需要记录的第 i 项操作,ops 遵循下述规则:

  1. 整数 x - 表示本回合新获得分数 x
  2. "+" - 表示本回合新获得的得分是前两次得分的总和。题目数据保证记录此操作时前面总是存在两个有效的分数。
  3. "D" - 表示本回合新获得的得分是前一次得分的两倍。题目数据保证记录此操作时前面总是存在一个有效的分数。
  4. "C" - 表示前一次得分无效,将其从记录中移除。题目数据保证记录此操作时前面总是存在一个有效的分数。

请你返回记录中所有得分的总和。

def calPoints(self, operations: List[str]) -> int:
        stack = []
        for i in operations:
            if i == 'C':
                if stack:
                    stack.pop()
            elif i == 'D':
                d = stack[-1]*2
                stack.append(d)
            elif i =='+':
                add = stack[-1]+stack[-2]
                stack.append(add)
            else:
                stack.append(int(i))
        return sum(stack)

 机器人能否返回原点

在二维平面上,有一个机器人从原点 (0, 0) 开始。给出它的移动顺序,判断这个机器人在完成移动后是否在 (0, 0) 处结束。

移动顺序由字符串 moves 表示。字符 move[i] 表示其第 i 次移动。机器人的有效动作有 R(右),L(左),U(上)和 D(下)。

如果机器人在完成所有动作后返回原点,则返回 true。否则,返回 false。

注意:机器人“面朝”的方向无关紧要。 “R” 将始终使机器人向右移动一次,“L” 将始终向左移动等。此外,假设每次移动机器人的移动幅度相同。

x , y = 0 , 0
        for i in moves:
            match i :
                case 'R':
                    x += 1
                case 'L':
                    x -= 1
                case 'U':
                    y += 1
                case 'D':
                    y -= 1
        if x == 0 and y == 0:
            return True
        else:
            return False

找出井字棋的获胜者 

方法多样,核心思维就是二维平面X轴,Y轴的值变没变。

也可以用内置函数count来判断次数是否一致来判断。

井字棋 是由两个玩家 A 和 B 在 3 x 3 的棋盘上进行的游戏。井字棋游戏的规则如下:

玩家轮流将棋子放在空方格 (' ') 上。
第一个玩家 A 总是用 'X' 作为棋子,而第二个玩家 B 总是用 'O' 作为棋子。
'X' 和 'O' 只能放在空方格中,而不能放在已经被占用的方格上。
只要有 3 个相同的(非空)棋子排成一条直线(行、列、对角线)时,游戏结束。
如果所有方块都放满棋子(不为空),游戏也会结束。
游戏结束后,棋子无法再进行任何移动。
给你一个数组 moves,其中 moves[i] = [rowi, coli] 表示第 i 次移动在 grid[rowi][coli]。如果游戏存在获胜者(A 或 B),就返回该游戏的获胜者;如果游戏以平局结束,则返回 "Draw";如果仍会有行动(游戏未结束),则返回 "Pending"。

你可以假设 moves 都 有效(遵循 井字棋 规则),网格最初是空的,A 将先行动。

class Solution:
    def tictactoe(self, moves: List[List[int]]) -> str:
        matrix = [[None for _ in range(3)] for _ in range(3)]  
        flag = 0
        for i in range(len(moves)):
            if flag == 0:
                matrix[moves[i][0]][moves[i][1]] = 'x'
                flag = 1                               
            else:
                matrix[moves[i][0]][moves[i][1]] = 'o'  
                flag = 0
        len_moves =len(moves)

        for i in range(3):
            if matrix[i][0] == matrix[i][1] == matrix[i][2]:
                if matrix[i][0] == 'x':
                    return 'A'
                elif  matrix[i][0] == 'o':
                    return 'B'
        for i in range(3):
            if matrix[0][i] == matrix[1][i] == matrix[2][i]:
                if matrix[0][i] == 'x':
                    return 'A'
                elif matrix[0][i] == 'o':
                    return 'B'
        if matrix[0][0] == matrix[1][1] == matrix[2][2]:
            if matrix[0][0] == 'x':
                return 'A'
            elif  matrix[0][0] == 'o':
                return 'B'
        if matrix[0][2] == matrix[1][1] == matrix[2][0]:
            if matrix[0][2] == 'x':
                return 'A'
            elif matrix[0][2] == 'o':
                return 'B'
        if len_moves == 9:
            return 'Draw'
        else:
            return 'Pending'

 

输入:moves = [[0,0],[2,0],[1,1],[2,1],[2,2]]
输出:"A"
解释:"A" 获胜,他总是先走。

先创建一个3*3棋盘,然后根据测试用例来自己下棋,填入x,y。最后我用的本办法三横三竖加交叉判断的,代码还能优化,判断的时候有提前结束的情况,我懒得考虑了。判断的时候一定要elif,不然空的三个相等,如果用else判断‘o’会导致误判成B获胜。