文件
文件的打开模式和文件对象方法
http://bbs.fishc.com/thread-45279-1-1.html
(出处: 鱼C论坛)
模块
import …
os模块
os.path模块
os、os.path 模块中关于文件、目录常用的函数使用方法
http://bbs.fishc.com/thread-45512-1-1.html
(出处: 鱼C论坛)
pickle模块(泡菜模块):将你的数据对象保存为二进制文件
先以‘wb’模式open文件:
存储数据
先以‘wb’模式open文件;
pickle.dump(date,file)
读取数据
先以‘rb’模式open文件;
pickle.load(date,file)
exception
Python 标准异常总结
http://bbs.fishc.com/thread-45814-1-1.html
(出处: 鱼C论坛)
try-except-finally语句
try:
检测范围
except [Exception[as reason]]:
出现exception后的处理代码
finally:
无论如何都会执行的代码
try:
sum=1+'1'
f=open('我为什么是一个文件')
print(f.read())
f.close()
except OSError as reason:
print('文件出错\n原因是:'+str(reason))
except TypeError as reason:
print('类型错误\n错误原因是:'+str(reason))
except:
print('出错了\n')
try:
sum=1+'1'
f=open('我为什么是一个文件')
print(f.read())
f.close()
except(OSError,TypeError):
print('出错了\n')
try:
f=open('d:\\a.txt','w')
print(f.write('我存在了'))
sum=1+'1'
except OSError as reason:
print('文件出错\n原因是:'+str(reason))
except TypeError as reason:
print('类型错误\n错误原因是:'+str(reason))
finally:
f.close()#无论如何都会执行
调用栈
如果错误没有被捕获,它就会一直往上抛,最后被Python解释器捕获,打印一个错误信息,然后程序退出。出错的时候,一定要分析错误的调用栈信息,才能定位错误的位置。来看看err.py:
# err.py:
def foo(s):
return 10 / int(s)
def bar(s):
return foo(s) * 2
def main():
bar('0')
main()
执行,结果如下:
$ python3 err.py
Traceback (most recent call last):#告诉我们这是错误的跟踪信息。
File "err.py", line 11, in <module>#调用main()出错了,在代码文件err.py的第11行代码,但原因是第9行
main()
File "err.py", line 9, in main#调用bar('0')出错了,在代码文件err.py的第9行代码,但原因是第6行
bar('0')
File "err.py", line 6, in bar#原因是return foo(s) * 2这个语句出错了,但这还不是最终原因
return foo(s) * 2
File "err.py", line 3, in foo#原因是return 10 / int(s)这个语句出错了,这是错误产生的源头.
return 10 / int(s)
ZeroDivisionError: division by zero#根据错误类型ZeroDivisionError,我们判断,int(s)本身并没有出错,但是int(s)返回0,在计算10 / 0时出错,至此,找到错误源头。
出错并不可怕,可怕的是不知道哪里出错了。解读错误信息是定位错误的关键。我们从上往下可以看到整个错误的调用函数链。
如果不捕获错误,自然可以让Python解释器来打印出错误堆栈,但程序也被结束了。既然我们能捕获错误,就可以把错误堆栈打印出来,然后分析错误原因,同时,让程序继续执行下去。
记录错误
如果不捕获错误,自然可以让Python解释器来打印出错误堆栈,但程序也被结束了。既然我们能捕获错误,就可以把错误堆栈打印出来,然后分析错误原因,同时,让程序继续执行下去。
记录错误:logging模块
Python内置的logging模块可以非常容易地记录错误信息:
# err_logging.py
import logging#
def foo(s):
return 10 / int(s)
def bar(s):
return foo(s) * 2
def main():
try:
bar('0')
except Exception as e:
logging.exception(e)#
main()
print('END')
同样是出错,但程序打印完错误信息后会继续执行,并正常退出:
$ python3 err_logging.py
ERROR:root:division by zero
Traceback (most recent call last):
File "err_logging.py", line 13, in main
bar('0')
File "err_logging.py", line 9, in bar
return foo(s) * 2
File "err_logging.py", line 6, in foo
return 10 / int(s)
ZeroDivisionError: division by zero
END
通过配置,logging还可以把错误记录到日志文件里,方便事后排查。
抛出错误:raise语句
>>> 1/0
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
1/0
ZeroDivisionError: division by zero
>>> raise ZeroDivisionError
Traceback (most recent call last):
File "<pyshell#9>", line 1, in <module>
raise ZeroDivisionError
ZeroDivisionError
>>> raise ZeroDivisionError('除数为0')
Traceback (most recent call last):
File "<pyshell#10>", line 1, in <module>
raise ZeroDivisionError('除数为0')
ZeroDivisionError: 除数为0
因为错误是class,捕获一个错误就是捕获到该class的一个实例。因此,错误并不是凭空产生的,而是有意创建并抛出的。Python的内置函数会抛出很多类型的错误,我们自己编写的函数也可以抛出错误。
如果要抛出错误,首先根据需要,可以定义一个错误的class,选择好继承关系(只有在必要的时候才定义我们自己的错误类型。如果可以选择Python已有的内置的错误类型(比如ValueError,TypeError),尽量使用Python内置的错误类型。),然后,用raise语句抛出一个错误的实例:
# err_raise.py
class FooError(ValueError):#定义一个错误的class
pass
def foo(s):
n = int(s)
if n==0:
raise FooError('invalid value: %s' % s)#抛出自定义的错误
return 10 / n
foo('0')
执行,可以最后跟踪到我们自己定义的错误:
$ python3 err_raise.py
Traceback (most recent call last):
File "err_throw.py", line 11, in <module>
foo('0')
File "err_throw.py", line 8, in foo
raise FooError('invalid value: %s' % s)
__main__.FooError: invalid value: 0
最后,我们来看另一种错误处理的方式:
# err_reraise.py
def foo(s):
n = int(s)
if n==0:
raise ValueError('invalid value: %s' % s)
return 10 / n
def bar():
try:
foo('0')
except ValueError as e:
print('ValueError!')
raise
bar()
在bar()函数中,我们明明已经捕获了错误,但是,打印一个ValueError!后,又把错误通过raise语句抛出去了,这不有病么?
其实这种错误处理方式不但没病,而且相当常见。捕获错误目的只是记录一下,便于后续追踪。但是,由于当前函数不知道应该怎么处理该错误,所以,最恰当的方式是继续往上抛,让顶层调用者去处理。好比一个员工处理不了一个问题时,就把问题抛给他的老板,如果他的老板也处理不了,就一直往上抛,最终会抛给CEO去处理。
else语句
if-else
while-else;for-else
try-else
try:
int('123')
except ValueError as reason:
print('出错了\n'+str(reason))
else:
print('没有异常')
with语句
try:
f=open('data.txt','w')
for each_line in f:
print(each_line)
except OSError as reason:
print('出错了\n'+str(reason))
finally:
f.close()
try:
with open('data.txt','w') as f:#自动调用f.close()
for each_line in f:
print(each_line)
except OSError as reason:
print('出错了\n'+str(reason))
调试
1.第一种方法简单直接粗暴有效,就是用print()把可能有问题的变量打印出来看看。
2.凡是用print()来辅助查看的地方,都可以用断言(assert)来替代。
3.把print()替换为logging是第3种方式,和assert比,logging不会抛出错误,而且可以输出到文件.允许你指定记录信息的级别,有debug,info,warning,error等几个级别.
4.IDE:如果要比较爽地设置断点、单步执行,就需要一个支持调试功能的IDE。虽然用IDE调试起来比较方便,但是最后你会发现,logging才是终极武器。
assert断言
assert False程序自动崩溃并抛出AssertionError的异常
>>> assert 3>4
Traceback (most recent call last):
File "<pyshell#26>", line 1, in <module>
assert 3>4
AssertionError
程序中如果到处充斥着assert,和print()相比也好不到哪去。不过,启动Python解释器时可以用-O参数来关闭assert:
$ python -O err.py
Traceback (most recent call last):
...
ZeroDivisionError: division by zero
关闭后,你可以把所有的assert语句当成pass来看。
本文介绍了Python中的文件操作,包括文件打开模式和文件对象方法,还详细讲解了OS模块和异常处理,如try-except-finally语句、调用栈分析、logging模块记录错误、raise语句抛出错误,以及使用else和with语句进行错误处理。此外,文章还探讨了Python的调试方法,如assert断言和使用IDE进行调试。
230

被折叠的 条评论
为什么被折叠?



