2.4 __init__.py
文件
__init__.py
的作用
标识包:
__init__.py
文件的存在标志着该目录是一个 Python 包。如果没有
__init__.py
文件,Python 会将目录视为普通目录,无法通过包的方式导入其中的模块。
初始化包:
当包或包中的模块被导入时,
__init__.py
文件中的代码会自动执行。可以在这里编写包的初始化逻辑,例如设置包级别的变量、导入子模块或执行其他初始化操作。
定义包的接口:
可以在
__init__.py
中定义__all__
变量,明确指定通过from package import *
导入时哪些模块或对象是公开的。也可以在
__init__.py
中导入包内的模块或子包,简化用户的导入方式。
命名空间管理:
__init__.py
文件可以帮助管理包的命名空间,确保包内的模块和子包能够正确导入和使用。
__all__
的作用
控制
from module import \*
的行为:默认情况下,
from module import *
会导入模块中所有不以_
开头的对象。如果定义了
__all__
,则只有__all__
中列出的对象会被导入。
明确公开接口:
通过
__all__
,开发者可以明确告诉用户哪些对象是模块或包的公开接口,哪些是内部实现细节。这是一种良好的编程实践,有助于提高代码的可维护性和可读性。
防止意外导入:
如果没有
__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
遵循下述规则:
- 整数
x
- 表示本回合新获得分数x
"+"
- 表示本回合新获得的得分是前两次得分的总和。题目数据保证记录此操作时前面总是存在两个有效的分数。"D"
- 表示本回合新获得的得分是前一次得分的两倍。题目数据保证记录此操作时前面总是存在一个有效的分数。"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获胜。