[请教问题] 异常处理 finally 中的内容在 pycharm 编辑器中会报错,大神帮忙看下,多谢。

2018-07-29 16:45:28 +08:00
 tukey
def handle():
....try:
........f = open('./html/index.html', 'r')
....except IOError:
........s = 'xx'
........a = 11
....else:
........s = 'pp'
........a = 22
........f.close()
....finally:
........print(a)
........print(s)
handle()

问题:程序 finally 中的内容在 pycharm 编辑器中会报错 local variable 'a' referenced before assignment,但是执行没有问题。
2399 次点击
所在节点    Python
17 条回复
billgreen1
2018-07-29 17:25:06 +08:00
你这个程序,如果 try except 之间的代码比较多,出现 IOError 之外的,exception/error, 会出现什么情况?
coffeSlider
2018-07-29 17:28:53 +08:00
英语水平为 0 啊
zwh2698
2018-07-29 19:18:48 +08:00
作用域是多大,考虑一下
tukey
2018-07-29 20:13:08 +08:00
@zwh2698 谢谢, 我把 finally 去掉,然后 finally 里的语句向前缩进 4 个空格,就不报错了。所以这两种情况对比,我就没搞懂。
xenme
2018-07-29 20:22:38 +08:00
楼上提到了作用域。
如果在 as 前面抛异常了,那么 as 可能都没内容。所以会挂
zhangpeter
2018-07-30 07:03:33 +08:00
else 和 finally 里不是同一个作用域,虽然语句缩进一样
tukey
2018-07-30 08:52:38 +08:00
@zhangpeter 但是这样就可以,他们作用域是一个吗?
def handle():
....try:
........f = open('./html/index.html', 'r')
....except IOError:
........s = 'xx'
........a = 11
....else:
........s = 'pp'
........a = 22
........f.close()

print(a)
print(s)
handle()
atz
2018-07-30 09:12:56 +08:00
一般打开文件用 with open("xxxxxx") as f:
guyskk0x0
2018-07-30 10:53:56 +08:00
@tukey 1 楼已经解释清楚了,仔细看
zhangpeter
2018-07-30 11:18:59 +08:00
推荐一篇讲作用域的文章,地址在 https://gist.github.com/zhang0peter/68208bc046db73ced8bc439006c7eb2a
SimbaPeng
2018-07-30 11:54:51 +08:00
楼上的真的会 Python 么?别在这里误人子弟了,try, except,else,finally 这些都不会产生新的作用域好吧。楼主的问题应该是出现了未捕获到的异常,导致 s 和 a 的赋值语句并未执行,然后 finally 里的异常会覆盖掉 try 里的异常。
tukey
2018-07-30 15:03:02 +08:00
@billgreen1
@SimbaPeng
感谢大家
=====================
你是说我可能 try...except 中语句多的话,有一个异常没有捕获到,导致我 except IOError 和 else 中两个分支中的语句都没有执行,那么 finally 中的变量我就没有定义了。如果是这样的话,那么为什么我 7 楼中的程序没有 pycharm 提示呢?因为如果有一个异常没有捕获导致变量未定义的话。
=====================
try...except/else...finally 我个人的理解是这样的,try 无论是否有异常,都会选择 except 或者 else 中的一个分支执行(如果异常我都捕获到了),然后再执行 finally,所以在 except 和 else 分支中我都对变量进行了赋值,在 finally 中应该不涉及到 pycharm 的提示信息“赋值前就引用变量”
SimbaPeng
2018-07-30 15:15:56 +08:00
@tukey 你 7 楼的程序打印的根本就不是函数里的变量,函数里的是局部变量,你下面 print 的是全局变量
tukey
2018-07-30 15:22:41 +08:00
@SimbaPeng 不好意思,程序是下面这样的,print(a)放在和 try 并列的位置,不是在函数外面。我在 pycharm 中可以运行且编辑器未提示报错。
def handle():
....try:
........f = open('./html/index.html', 'r')
....except IOError:
........s = 'xx'
........a = 11
....else:
........s = 'pp'
........a = 22
........f.close()

....print(a)
....print(s)

handle()
SimbaPeng
2018-07-30 15:32:08 +08:00
@tukey 你首先确定程序进了 except 还是 else,然后你用命令行去执行。
aimiyooo
2018-07-30 16:51:42 +08:00
1 楼正解,出现了除 IOError 异常的其他异常。顺便说下最好使用 with as 语法,这样就不用 close 了。如果像楼主这样写的话,close 应该写在 finally 里面。
tukey
2018-07-30 17:33:11 +08:00
@aimiyooo close 写在 finally 里面编辑器会提示错误,我的理解是,如果打开文件有错误,那么引用 f = open()中的 f 是没有意义的,放在 finally 中 f 是一个无意义的量,没法关闭,因此要将 f.close()放在 else 中,打开文件没有报错那么引用 f 才需要关闭,打开失败的话就是没打开,不需要关闭。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/475103

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX