一、异常处理
1.1.格式语法
python提供了两个非常重要的功能来处理python程序在运行中出现的异常和错误
捕捉异常可以使用try/except语句。
try/except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理。
如果你不想在异常发生时结束你的程序,只需在try里捕获它。
语法
try:
<语句> #运行别的代码
except <名字>:
<语句> #如果在try部份引发了异常
except <名字>,<数据>:
<语句> #如果引发了异常,获得附加的数据
else:
<语句> #如果没有异常发生
finally:
<语句> #不管执行是否有异常,最终都要执行,可省略
try的工作原理是:
当开始一个try语句后,python就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try子句先执行,接下来会发生什么依赖于执行时是否出现异常。
如果当try后的语句执行时发生异常,python就跳回到try并执行第一个匹配该异常的except子句,异常处理完毕,控制流就通过整个try语句(除非在处理异常时又引发新的异常)。
如果在try后的语句里发生了异常,却没有匹配的except子句,异常将被递交到上层的try,或者到程序的最上层(这样将结束程序,并打印缺省的出错信息)。
如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话),然后控制流通过整个try语句,此模块可以省略
不管是否有异常,finally中的语句最终都需要执行,finally的语句可以省略
1.2.python标准异常
异常名称 | 描述 |
BaseException | 所有异常的基类 |
SystemExit | 解释器请求退出 |
KeyboardInterrupt | 用户中断执行(通常是输入^C) |
Exception | 常规错误的基类 |
StopIteration | 迭代器没有更多的值 |
GeneratorExit | 生成器(generator)发生异常来通知退出 |
StandardError | 所有的内建标准异常的基类 |
ArithmeticError | 所有数值计算错误的基类 |
FloatingPointError | 浮点计算错误 |
OverflowError | 数值运算超出最大限制 |
ZeroDivisionError | 除(或取模)零 (所有数据类型) |
AssertionError | 断言语句失败 |
AttributeError | 对象没有这个属性 |
EOFError | 没有内建输入,到达EOF 标记 |
EnvironmentError | 操作系统错误的基类 |
IOError | 输入/输出操作失败 |
OSError | 操作系统错误 |
WindowsError | 系统调用失败 |
ImportError | 导入模块/对象失败 |
LookupError | 无效数据查询的基类 |
IndexError | 序列中没有此索引(index) |
KeyError | 映射中没有这个键 |
MemoryError | 内存溢出错误(对于Python 解释器不是致命的) |
NameError | 未声明/初始化对象 (没有属性) |
UnboundLocalError | 访问未初始化的本地变量 |
ReferenceError | 弱引用(Weak reference)试图访问已经垃圾回收了的对象 |
RuntimeError | 一般的运行时错误 |
NotImplementedError | 尚未实现的方法 |
SyntaxError | Python 语法错误 |
IndentationError | 缩进错误 |
TabError | Tab 和空格混用 |
SystemError | 一般的解释器系统错误 |
TypeError | 对类型无效的操作 |
ValueError | 传入无效的参数 |
UnicodeError | Unicode 相关的错误 |
UnicodeDecodeError | Unicode 解码时的错误 |
UnicodeEncodeError | Unicode 编码时错误 |
UnicodeTranslateError | Unicode 转换时错误 |
Warning | 警告的基类 |
DeprecationWarning | 关于被弃用的特征的警告 |
FutureWarning | 关于构造将来语义会有改变的警告 |
OverflowWarning | 旧的关于自动提升为长整型(long)的警告 |
PendingDeprecationWarning | 关于特性将会被废弃的警告 |
RuntimeWarning | 可疑的运行时行为(runtime behavior)的警告 |
SyntaxWarning | 可疑的语法的警告 |
UserWarning | 用户代码生成的警告 |
示例
import codecs
try:
with codecs.open("testfile.txt","w") as f:
f.write("这是一个测试文件,用于测试异常")
except IOError:
print("Error:没有找到文件或读取文件失败")
else:
print("内容写入文件成功")
finally:
print("异常处理执行的最后一步")
取消testfile.txt文件写权限
chmod -w testfile.txt
再执行结果如下
Error:没有找到文件或读取文件失败
异常处理执行的最后一步
1.3.抛出异常
Python 使用 raise 语句抛出一个指定的异常。
raise 唯一的一个参数指定了要被抛出的异常。它必须是一个异常的实例或者是异常的类(也就是 Exception 的子类)。
如果你只想知道这是否抛出了一个异常,并不想去处理它,那么一个简单的 raise 语句就可以再次把它抛出。
try:
raise NameError("this is error")
except NameError:
print("An Exception flew by!")
raise
1.4.用户自定义异常
你可以通过创建一个新的exception类来拥有自己的异常。异常应该继承自 Exception 类,或者直接继承,或者间接继承
#自定义异常类
class MyError(Exception):
def __init__(self,value):
self.value=value
def __str__(self):
return repr(self.value)
try:
raise MyError(2*2)
except MyError as e:
print("define an exception by myself ,value is {0}".format(e.value))
结果
define an exception by myself ,value is 4
二、内置常用模块
模块和目录的区别,是否有__init__.py,如果有,就是模块
2.1.datetime
2.1.1.时间格式化符号
%y 两位数的年份表示(00-99)
%Y 四位数的年份表示(000-9999)
%m 月份(01-12)
%d 月内中的一天(0-31)
%H 24小时制小时数(0-23)
%I 12小时制小时数(01-12)
%M 分钟数(00=59)
%S 秒(00-59)
%a 本地简化星期名称
%A 本地完整星期名称
%b 本地简化的月份名称
%B 本地完整的月份名称
%c 本地相应的日期表示和时间表示
%j 年内的一天(001-366)
%p 本地A.M.或P.M.的等价符
%U 一年中的星期数(00-53)星期天为星期的开始
%w 星期(0-6),星期天为星期的开始
%W 一年中的星期数(00-53)星期一为星期的开始
%x 本地相应的日期表示
%X 本地相应的时间表示
%Z 当前时区的名称
%% %号本身
2.1.2.datetime类
2.1.2.1.datetime.datetime类
引入类如下:from datetime import datetime示例1from datetime import datetime
#获取当前时间
print(datetime.now())
#获取当前时间的年份
print(datetime.now().year)
#获取当前时间的月份
print(datetime.now().month)
#获取当前时间的天
print(datetime.now().day)
#获取当前时间的小时
print(datetime.now().hour)
#获取当前时间的分钟
print(datetime.now().minute)
#获取当前时间的秒数
print(datetime.now().second)
#获取当前时间的毫秒
print(datetime.now().microsecond)
示例2from datetime import datetime
# 时间格式化,将date类型的日期转换成字符串型
print(datetime.now().strftime("%Y-%m-%d"))#将字符串类型的日期转换成日期类型
print(datetime.now().strptime("2018-04-23","%Y-%m-%d"))
结果2018-04-23
2018-04-23 00:00:00
2.1.2.2.datetime.timedelta类
对日期和时间进行加减实际上就是把datetime往后或往前计算,得到新的datetime示例import datetime
print("现在的时间为:{0}".format(datetime.datetime.now()))
print("3小时前的时间为:{0}".format(datetime.datetime.now()+datetime.timedelta(hours=-3)))
print("5天后的时间为:{0}".format(datetime.datetime.now()+datetime.timedelta(days=+5)))
结果现在的时间为:2018-04-23 13:41:43.092501
3小时前的时间为:2018-04-23 10:41:43.092501
5天后的时间为:2018-04-28 13:41:43.092501
2.2.time
2.2.1.时间元组
很多Python函数用一个元组装起来的9组数字处理时间:
序号 | 字段 | 值 |
0 | 4位数年 | 2008 |
1 | 月 | 1 到 12 |
2 | 日 | 1到31 |
3 | 小时 | 0到23 |
4 | 分钟 | 0到59 |
5 | 秒 | 0到61 (60或61 是闰秒) |
6 | 一周的第几日 | 0到6 (0是周一) |
7 | 一年的第几日 | 1到366 (儒略历) |
8 | 夏令时 | -1, 0, 1, -1是决定是否为夏令时的旗帜 |
上述也就是struct_time元组。这种结构具有如下属性:
序号 | 属性 | 值 |
0 | tm_year | 2008 |
1 | tm_mon | 1 到 12 |
2 | tm_mday | 1 到 31 |
3 | tm_hour | 0 到 23 |
4 | tm_min | 0 到 59 |
5 | tm_sec | 0 到 61 (60或61 是闰秒) |
6 | tm_wday | 0到6 (0是周一) |
7 | tm_yday | 一年中的第几天,1 到 366 |
8 | tm_isdst | 是否为夏令时,值有:1(夏令时)、0(不是夏令时)、-1(未知),默认 -1 |
2.2.2.time
2.2.2.1.time.time
获取时间戳时间戳:就是时间戳都以自从1970年1月1日午夜(历元)经过了多长时间来表示。时间戳单位最适于做日期运算。但是1970年之前的日期就无法以此表示了。太遥远的日期也不行,UNIX和Windows只支持到2038年。
示例
import time
print("当前时间戳为:{0}".format(time.time()))结果当前时间戳为:1524462713.488501
2.2.2.2.time.localtime
获取当前时间,从返回浮点数的时间辍方式向时间元组转换,只要将浮点数传递给如localtime之类的函数。import time
print("本地时间为:{0}".format(time.localtime(time.time())))结果本地时间为:time.struct_time(tm_year=2018, tm_mon=4, tm_mday=23, tm_hour=13, tm_min=58, tm_sec=52, tm_wday=0, tm_yday=113, tm_isdst=0)
2.2.2.3.time.strftime
格式化日期
示例
import time
print("本地时间为:{0}".format(time.localtime(time.time())))
print("本地时间格式化后为:{0}".format(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())))
结果
本地时间为:time.struct_time(tm_year=2018, tm_mon=4, tm_mday=23, tm_hour=14, tm_min=4, tm_sec=21, tm_wday=0, tm_yday=113, tm_isdst=0)
本地时间格式化后为:2018-04-23 14:04:21
2.2.2.4.time.altzone
返回格林威治西部的夏令时地区的偏移秒数。如果该地区在格林威治东部会返回负值(如西欧,包括英国)。对夏令时启用地区才能使用。示例import time
print("格林威治西部的夏令时地区的偏移秒数:{0}".format(time.altzone))结果格林威治西部的夏令时地区的偏移秒数:-32400
2.2.2.5.time.asctime([tupletime])
接受时间元组并返回一个可读的形式为"Mon Apr 23 14:13:27 2018"(2018年04月23日 周一14时13分27秒)的24个字符的字符串。
示例
import time
t=time.localtime()
print("time.asctime: {0}".format(time.asctime(t)))
2.2.2.6.time.clock
Python time clock() 函数以浮点数计算的秒数返回当前的CPU时间。用来衡量不同程序的耗时,比time.time()更有用。
这个需要注意,在不同的系统上含义不同。在UNIX系统上,它返回的是"进程时间",它是用秒表示的浮点数(时间戳)。而在WINDOWS中,第一次调用,返回的是进程运行的实际时间。而第二次之后的调用是自第一次调用以后到现在的运行时间。返回值:在第一次调用的时候,返回的是程序运行的实际时间;
以第二次之后的调用,返回的是自第一次调用后,到这次调用的时间间隔
在win32系统下,这个函数返回的是真实时间(wall time),而在Unix/Linux下返回的是CPU时间
示例
import time
def procedure():
time.sleep(3)
t1=time.clock()
procedure()
print(time.clock()-t1)结果2.9992477733640404
2.2.2.7.time.ctime([secs])
作用相当于asctime(localtime(secs)),未给参数相当于asctime()
示例
import time
print("time.ctime(): {0}".format(time.ctime()))
结果
2.2.2.8.time.gmtime([secs])
接收时间辍(1970纪元后经过的浮点秒数)并返回格林威治天文时间下的时间元组t。注:t.tm_isdst始终为0import time
print("time.gtime(): {0}".format(time.gmtime()))结果time.gtime(): time.struct_time(tm_year=2018, tm_mon=4, tm_mday=23, tm_hour=6, tm_min=30, tm_sec=33, tm_wday=0, tm_yday=113, tm_isdst=0)
2.2.2.9.time.mktime
Python time mktime() 函数执行与gmtime(), localtime()相反的操作,它接收struct_time对象作为参数,返回用秒数来表示时间的浮点数。
如果输入的值不是一个合法的时间,将触发 OverflowError 或 ValueError。语法time.mktime(t)t -- 结构化的时间或者完整的9位元组元素。返回值返回用秒数来表示时间的浮点数。示例import time
t=(2018, 4, 23, 6, 30, 33, 0, 113, 0)
print(time.mktime(t))结果1524436233.0
2.2.2.10.time.strftime(fmt[,tupletime])
接收以时间元组,并返回以可读字符串表示的当地时间,格式由fmt决定。import time
print(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()))结果2018-04-23 15:08:31
2.2.2.11.time.strptime(str,fmt="%a %b %d %H:%M:%S %Y")
根据fmt的格式把一个时间字符串解析为时间元组。import time
print(time.strptime("2018-04-23 15:15:12","%Y-%m-%d %H:%M:%S"))结果time.struct_time(tm_year=2018, tm_mon=4, tm_mday=23, tm_hour=15, tm_min=15, tm_sec=12, tm_wday=0, tm_yday=113, tm_isdst=-1)
2.3.Calendar
此模块的函数都是日历相关的,例如打印某月的字符月历。
星期一是默认的每周第一天,星期天是默认的最后一天。更改设置需调用calendar.setfirstweekday()函数。模块包含了以下内置函数:
序号 | 函数及描述 |
1 | calendar.calendar(year,w=2,l=1,c=6) 返回一个多行字符串格式的year年年历,3个月一行,间隔距离为c。 每日宽度间隔为w字符。每行长度为21* W+18+2* C。l是每星期行数。 |
2 | calendar.firstweekday( ) 返回当前每周起始日期的设置。默认情况下,首次载入caendar模块时返回0,即星期一。 |
3 | calendar.isleap(year) 是闰年返回True,否则为false。 |
4 | calendar.leapdays(y1,y2) 返回在Y1,Y2两年之间的闰年总数。 |
5 | calendar.month(year,month,w=2,l=1) 返回一个多行字符串格式的year年month月日历,两行标题,一周一行。每日宽度间隔为w字符。每行的长度为7* w+6。l是每星期的行数。 |
6 | calendar.monthcalendar(year,month) 返回一个整数的单层嵌套列表。每个子列表装载代表一个星期的整数。Year年month月外的日期都设为0;范围内的日子都由该月第几日表示,从1开始。 |
7 | calendar.monthrange(year,month) 返回两个整数。第一个是该月的星期几的日期码,第二个是该月的日期码。日从0(星期一)到6(星期日);月从1到12。 |
8 | calendar.prcal(year,w=2,l=1,c=6) 相当于 print calendar.calendar(year,w,l,c). |
9 | calendar.prmonth(year,month,w=2,l=1) 相当于 print calendar.calendar(year,w,l,c)。 |
10 | calendar.setfirstweekday(weekday) 设置每周的起始日期码。0(星期一)到6(星期日)。 |
11 | calendar.timegm(tupletime) 和time.gmtime相反:接受一个时间元组形式,返回该时刻的时间辍(1970纪元后经过的浮点秒数)。 |
12 | calendar.weekday(year,month,day) 返回给定日期的日期码。0(星期一)到6(星期日)。月份为 1(一月) 到 12(12月)。 |
2.4.Commands(python2专用)
用于执行shell命令
commands模块在python2环境中使用,在python3中已经废弃,被subprocess模块替代
2.4.1.commands.getoutput()
执行命令,返回结果信息
示例
import commands
print commands.getoutput("pwd")
2.4.2.commands.getoutput()
执行shell命令, 返回两个元素的元组tuple(status, result),status为int类型,表示shell运行结果的状态,0表示shell命令运行正确;result为输出的内容,string类型。
示例
import commands
print commands.getstatusoutput("pwd")
结果
2.5.subprocess
2.5.1.subprocess.getstatusoutput(cmd)
获得shell输出的内容,返回的数据结果是一个元组,第一位为shell运行结果的状态(0通过),第二位是输出的内容(string类型)
示例
import subprocess
print(subprocess.getstatusoutput("ls"))
结果
2.5.2.subprocess.getoutput(cmd)
接收字符串格式的命令,执行命令并返回执行结果,其功能类似于os.popen(cmd).read()和commands.getoutput(cmd)。
示例
import subprocess
print(subprocess.getoutput("ls"))
结果
2.5.3.subprocess.Popen
该类用于在一个新的进程中执行一个子程序
1.subprocess.Popen的构造函数
class subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=False,
startup_info=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=())
参数说明
args: 要执行的shell命令,可以是字符串,也可以是命令各个参数组成的序列。当该参数的值是一个字符串时,该命令的解释过程是与平台相关的,因此通常建议将args参数作为一个序列传递。
bufsize: 指定缓存策略,0表示不缓冲,1表示行缓冲,其他大于1的数字表示缓冲区大小,负数 表示使用系统默认缓冲策略。
stdin, stdout, stderr: 分别表示程序标准输入、输出、错误句柄。
preexec_fn: 用于指定一个将在子进程运行之前被调用的可执行对象,只在Unix平台下有效。
close_fds: 如果该参数的值为True,则除了0,1和2之外的所有文件描述符都将会在子进程执行之前被关闭。
shell: 该参数用于标识是否使用shell作为要执行的程序,如果shell值为True,则建议将args参数作为一个字符串传递而不要作为一个序列传递。
cwd: 如果该参数值不是None,则该函数将会在执行这个子进程之前改变当前工作目录。
env: 用于指定子进程的环境变量,如果env=None,那么子进程的环境变量将从父进程中继承。如果env!=None,它的值必须是一个映射对象。
universal_newlines: 如果该参数值为True,则该文件对象的stdin,stdout和stderr将会作为文本流被打开,否则他们将会被作为二进制流被打开。
startupinfo和creationflags: 这两个参数只在Windows下有效,它们将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如主窗口的外观,进程优先级等。
示例
import subprocess
p = subprocess.Popen('df -Th', stdout=subprocess.PIPE, shell=True)
print(p.stdout.read())
结果
2.5.3.subprocess.run()
执行指定的命令,等待命令执行完成后返回一个包含执行结果的CompletedProcess类的实例。
语法
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, timeout=None, check=False, universal_newlines=False)
参数说明:
•args: 要执行的shell命令,默认应该是一个字符串序列,如['df', '-Th']或('df', '-Th'),也可以是一个字符串,如'df -Th',但是此时需要把shell参数的值置为True。
•shell: 如果shell为True,那么指定的命令将通过shell执行。如果我们需要访问某些shell的特性,如管道、文件名通配符、环境变量扩展功能,这将是非常有用的。当然,python本身也提供了许多类似shell的特性的实现,如glob、fnmatch、os.walk()、os.path.expandvars()、os.expanduser()和shutil等。
•check: 如果check参数的值是True,且执行命令的进程以非0状态码退出,则会抛出一个CalledProcessError的异常,且该异常对象会包含 参数、退出状态码、以及stdout和stderr(如果它们有被捕获的话)。
•stdout, stderr:
•run()函数默认不会捕获命令执行结果的正常输出和错误输出,如果我们向获取这些内容需要传递subprocess.PIPE,然后可以通过返回的CompletedProcess类实例的stdout和stderr属性或捕获相应的内容;
•call()和check_call()函数返回的是命令执行的状态码,而不是CompletedProcess类实例,所以对于它们而言,stdout和stderr不适合赋值为subprocess.PIPE;
•check_output()函数默认就会返回命令执行结果,所以不用设置stdout的值,如果我们希望在结果中捕获错误信息,可以执行stderr=subprocess.STDOUT。
•input: 该参数是传递给Popen.communicate(),通常该参数的值必须是一个字节序列,如果universal_newlines=True,则其值应该是一个字符串。
•universal_newlines: 该参数影响的是输入与输出的数据格式,比如它的值默认为False,此时stdout和stderr的输出是字节序列;当该参数的值设置为True时,stdout和stderr的输出是字符串。
示例
import subprocess
subprocess.run(["ls","-l"])
结果
2.5.4.subprocess.call()
执行指定的命令,返回命令执行状态,其功能类似于os.system(cmd)。
语法
subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)
参数说明:
同subprocess.run
示例
subprocess.call(['ls', '-l', '/test'])
结果
ls: cannot access '/test': No such file or directory
2.5.5.subprocess.check_call()
执行指定的命令,如果执行成功则返回状态码,否则抛出异常。其功能等价于subprocess.run(..., check=True)。
语法
subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)
参数说明:
同subprocess.run
示例
import subprocess
subprocess.check_call('ls -l /test', shell=True)
结果
2.5.6.subprocess.check_output()
执行指定的命令,如果执行状态码为0则返回命令执行结果,否则抛出异常。
语法
subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False, timeout=None)
参数说明:
同subprocess.run
示例
import subprocess
ret = subprocess.check_output(['ls', '-l'], universal_newlines=True)
print(ret)
结果