【Python】Java程序员学习Python(六)— 流程控制、异常处理
和Java语言一样,Python也有基本的流程控制,简单了解下即可。
一、流程控制的元素
条件
条件就是布尔值或者布尔值的表达式,要么是True要么是False。
代码块
在Python中,代码块不是用大括号引起来的,而是靠统一的缩进来表示,相同的缩进代表相同的代码块。
二、分支语句
判断流程的关键字是if/else/elif,if的简单的示例如下,注意冒号的使用以及缩进的使用:
def hello(name): if(name=='yiwangzhibujian'): print('hello',name) hello('yiwangzhibujian') =======控制台输出======= hello yiwangzhibujian
if/else的示例:
def hello(name): if(name=='laizhezhikezhui'): print('i miss you') else: print('hello',name) hello('yiwangzhibujian') hello('laizhezhikezhui') ========控制台输出======== hello yiwangzhibujian i miss you
if/else/elif的示例:
def grade(result): if(result>80): print('A') elif(result>60): print('B') else: print('C') grade(61) ========控制台输出======== B
分支语句还是比较简单的,看看就会了。
二、循环
循环语句稍微复杂一点,但是看看也会了。
2.1 for循环
for循环是最基本的循环方式,Python中一般两种用法,第一种是循环指定的次数,这时候就需要range()区间了,示例如下:
for i in range(0,3): print(i) ========控制台输出======== 0 1 2
其实这种模式可以应用于所有可以能遍历的元素上,例如list、tuple、range、str、dict、set等等
for i in (1,2,3): print(i)
基本用法必须掌握。
2.2 while 循环
while循环用法和Java一样,掌握书写规范即可:
num=3 while num>0: print(num) num-=1 ========控制台输出======== 3 2 1
看一眼基本就会了。
2.3 break和continue
只要是支持循环的语言,这两个关键字都会支持的,用法和其他语言一样。
三、猜字游戏
练习分支语法的一个最经典程序就是猜字游戏,随机生成一个0-99的数字,给用户5次机会猜,猜对了恭喜,5次机会用完了没猜对就说运气不好。随机数需要引入random模块,就像Java的Random类一个性质,示例如下:
import random num=random.randint(0, 99)
编写代码完成要求,下面给出一个简单的例子:
import random result=random.randint(0, 99) time=5 print('现在玩一个猜字游戏!') while time>0: num=int(input('请输入你猜的数字?')) if(num==result): print('恭喜你答对了') break else: if num>result: print('猜大了,请再猜一次') else: print('猜小了,请再猜一次') time-=1 if time==0: print('运气太不好了,没猜对,答案是',result)
这个程序写完了,流程语法就没有问题了。
四、异常处理
4.1 异常基本语法
异常基本语法如下:
try: <statements> except Exception1 as e: <statements> except (Exception2,Exception3) as e: <statements> except Exception4: <statements> except: <statements> else: <statements> finally: <statements>
简单介绍:
- try:后面的代码块为假定可能出现异常的代码
- except:为要捕获的异常
- else:为当try的语句块没有异常发生时,执行的代码,但try最后的语句为return就不执行
- finally:不管是否发生异常都会执行的的代码,即便前面有return语句,依然会执行
- 可以捕获一个异常,也可捕获多个异常,多个异常放在一个tuple中
- 可以有选择的将异常赋值给一个变量,用于后续处理
- except语句不指定异常时,捕获所有,和except BaseException:等价,Exception为所以异常的父类
注意它们的使用顺序,try->except->else->finally
4.2 异常堆栈的打印
捕获异常后如果直接使用print()只会打印简略信息,可以引用logging模块来打印。
import logging try: 1/0 except Exception as e: logging.exception(e)
还有其他写法,后续补上。
4.3 抛出异常
抛出异常分为两种,一种时主动抛出,另一种是捕获后再次抛出,主动抛出使用关键字raise关键字:
try: raise Exception except Exception as e: logging.exception(e)
另外一种捕获后抛出,直接在捕获语句中使用raise即可:
try: raise Exception except Exception as e: raise
强烈建议:请深思当前异常是否能够处理,若不能处理请抛出
4.4 自动关闭资源
很多时候我们都是在finally里面来关闭资源,避免出现异常导致资源没有被关闭,除了这种做法还可以使用with as来
with open('path') as file: <statements>
这样在语句执行完后会自动关闭资源,强烈建议使用此种方式。
4.5 异常层次
可以了解基本的异常,这样报错后能大概知道出了什么错:
BaseException:异常基类 +-- SystemExit:由 sys.exit() 函数引发此异常 +-- KeyboardInterrupt:当用户按下中断键(通常是 Delete 或 Control-C)时引发。执行期间,会定期检查中断 +-- GeneratorExit:在generator或coroutine关闭时触发 +-- Exception:所有内建的、非系统退出的异常,都是从该类派生的。此外,应该从该类派生所有用户定义的异常 +-- StopIteration:由内建函数next()和iterator的__next__()方法引发 +-- StopAsyncIteration:必须通过asynchronous iterator对象的__anext__()方法提高以停止迭代 +-- ArithmeticError:各种算术错误引发的内建异常的基类 | +-- FloatingPointError:当浮点数操作失败时引发。 | +-- OverflowError:当要表示算术运算的结果太大时引发。 | +-- ZeroDivisionError:当除法或取模运算的第 2 个参数为 0 时引发 +-- AssertionError:当 assert 语句失败时引发。 +-- AttributeError:当属性引用(参见 Attribute references)或赋值失败时引发。 +-- BufferError:当 buffer 相关的操作无法执行时引发。 +-- EOFError:在input()函数未读取任何数据时遇到文件结束条件(EOF)时触发。 +-- ImportError:在import语句未能找到模块定义或从 ... import 无法找到要导入的名称。 +-- ModuleNotFoundError:模块找不到时发生的异常 +-- LookupError:当用于映射或序列的键或索引无效时引发的异常的基类 | +-- IndexError:当序列下标超出取值范围时引发。 | +-- KeyError:当在现有键的集合中找不到映射的(字典)键时引发。 +-- MemoryError:当一个操作将内存耗尽,但情况仍可挽救时(通过删除某些对象)时引发 +-- NameError:当找不到本地或全局名称时引发。这仅适用于不合格的名称。关联值是一条错误消息,其中包括找不到的名称。 | +-- UnboundLocalError:当引用函数或方法局部变量,但变量没有绑定值时引发。 +-- OSError:当系统函数返回与系统相关的错误(包括I / O故障,例如“未找到文件”或“磁盘已满”(不适用于非法参数类型或其他偶发错误))时会引发此异常 | +-- BlockingIOError:在操作会阻止对象时触发。套接字设置为非阻塞操作。对应于errno EAGAIN,EALREADY,EWOULDBLOCK和EINPROGRESS。 | +-- ChildProcessError:在子进程上的操作失败时引发。对应于errno ECHILD。 | +-- ConnectionError:连接相关问题的基类。 | | +-- BrokenPipeError:在尝试在管道上写入时引发,而另一端已关闭,或试图在已关闭写入的套接字上写入。对应于errno EPIPE和ESHUTDOWN。 | | +-- ConnectionAbortedError:连接尝试被对等体中止时引发的ConnectionError的子类。对应于errno ECONNABORTED。 | | +-- ConnectionRefusedError:连接尝试被对等体拒绝时引发的ConnectionError的子类。对应于errno ECONNREFUSED。 | | +-- ConnectionResetError:当连接被对等体重置时引发的ConnectionError的子类。对应于errno ECONNRESET。 | +-- FileExistsError:在尝试创建已存在的文件或目录时引发。对应于errno EEXIST。 | +-- FileNotFoundError:在请求文件或目录但不存在时引发。对应于errno ENOENT。 | +-- InterruptedError:在系统调用由传入信号中断时引发。对应于errno EINTR。 | +-- IsADirectoryError:在目录上请求文件操作(例如os.remove())时引发。对应于errno EISDIR。 | +-- NotADirectoryError:在对不是目录的某个目录请求目录操作(例如os.listdir())时引发。对应于errno ENOTDIR。 | +-- PermissionError:在尝试运行没有足够访问权限的操作(例如文件系统权限)时引发。对应于errno EACCES和EPERM。 | +-- ProcessLookupError:在给定进程不存在时引发。对应于errno ESRCH。 | +-- TimeoutError:在系统级别的系统函数超时时触发。对应于errno ETIMEDOUT +-- ReferenceError:当用一个由 weakref.proxy() 函数创建的弱引用代理,去访问引用者的属性,而该引用者已经被垃圾回收时,会引发此异常 +-- RuntimeError:当检出错误不属于任何其它类别时引发。 | +-- NotImplementedError:此异常是从 RuntimeError 派生的。当用户定义基类需要派生类重写方法时,抽象方法会引发该异常。 | +-- RecursionError:此异常是从 RuntimeError 派生的。当解释器检测到超出最大递归深度 +-- SyntaxError:当解析器遇到语法错误时引发。这可能发生在import语句中,在调用内建函数exec()或eval()脚本或标准输入(也是交互式) | +-- IndentationError:与不正确的缩进相关的语法错误的基类 | +-- TabError:当缩进中包含对制表符和空格的混用时引发 +-- SystemError:当解释器发现内部错误,但情况并没有看起来那么严重,不至于到要放弃所有希望的地步 +-- TypeError:当操作或函数应用于不合适类型的对象时引发。关联值是字符串,它提供有关类型不匹配的详细信息。 +-- ValueError:当内建操作或函数,接收到类型正确,但值不正确的参数,而且这种情况不能用诸如 IndexError 这样的更精确的异常进行描述时引发。 | +-- UnicodeError:当有关 Unicode 编码或解码错误出现时引发。 | +-- UnicodeDecodeError:当解码过程中出现的一个 Unicode 相关的错误时引发。 | +-- UnicodeEncodeError:当编码过程中出现的一个 Unicode 相关的错误时引发。 | +-- UnicodeTranslateError:当翻译过程中出现的一个 Unicode 相关的错误时引发。 +-- Warning:警告类别基类 +-- DeprecationWarning:弃用特性警告基类 +-- PendingDeprecationWarning:将来会被弃用特性的警告基类 +-- RuntimeWarning:可疑 Runtime 行为警告基类 +-- SyntaxWarning:有关可疑语法的警告的基类 +-- UserWarning:用户代码生成警告基类 +-- FutureWarning:将来会改变语义结构的警告基类 +-- ImportWarning:可能弄错模块导入警告基类 +-- UnicodeWarning:Unicode 相关的警告基类 +-- BytesWarning:与bytes和bytearray相关的警告的基类 +-- ResourceWarning:与资源使用相关的警告的基类