【问题标题】:what is making try: exit early?什么在尝试:提前退出?
【发布时间】:2010-11-24 01:06:43
【问题描述】:

在下面的函数中,是什么让try: 提前退出?如果我将相同的代码放在def 块之外,它就可以正常工作。

tiles = ['095D', '094M']
in_file = 'in_file'
out_file = 'out_file'
expression = ''' "FIELDNAME" LIKE 'STUFF' '''

def foobar(in_file, out_file, expression):
    print in_file, out_file, expression
    try:
        print 'this is trying'
        #pretty print tile list, from http://stackoverflow.com/questions/2399112/python-print-delimited-list
        tiles = ','.join(map(str,tiles))
        print 'made it past tiles!'
        print 'From %s \nselecting %s \ninto %s' % (in_file, tiles, out_file)

    except:
        print 'Made it to the except block!'

foobar(in_file, out_file, expression)

结果:

D:\> python xx-debug.py
in_file out_file  "FIELDNAME" LIKE 'STUFF'
this is trying
Made it to the except block!

same code not in a def 的结果:

this is trying
made it past tiles!
From in_file
selecting 095D,094M
into out_file

【问题讨论】:

  • 简单易行,初学者会做这样的事情。
  • @aaronasterling "Pokemon 异常处理 - 必须抓住它们!"
  • 你不应该except:而不指定例外。这也将捕获诸如 KeyboardInterrupt 之类的东西,这几乎不是您想要的。

标签: python


【解决方案1】:

它不起作用的原因是因为您在全局范围内定义了tiles。在您分配给tiles 的函数中。这使得tiles 成为函数中的本地范围名称。反过来,这意味着函数中的代码根本不会在全局范围内查找tiles

在分配中,您尝试获取 tiles(这是在本地分配之前。)这会导致引发异常,因为您尝试访问未分配的本地变量。

快速解决方法是使用global:

...
def foobar(in_file, out_file, expression):
    global tiles
    ...

正如其他人所说,不要只捕获异常而不对其进行处理。在调试代码时,您希望抛出异常,以便找到并修复原因!要么删除try...except,要么让except 接受异常并打印有关它的有用信息,如下所示:

try:
    ...
except Exception, e:
    print 'Oh noes!', e

这可能需要阅读很多内容,但是如果您阅读它,您会更好地理解 Python:

http://docs.python.org/reference/executionmodel.html

它解释了Python如何处理模块范围和函数范围内的变量定义等。它还涵盖了异常。

【讨论】:

  • 真正的 except 块是 except:\n\tprint gp.GetMessages()\n (ref) 我在构建最简单的错误重现时将其取出。感谢您让我了解正在发生的事情。
【解决方案2】:

异常输出:

Traceback (most recent call last):
  File "sof.py", line 19, in <module>
    foobar(in_file, out_file, expression)
  File "sof.py", line 11, in foobar
    tiles = ','.join(map(str,tiles))
UnboundLocalError: local variable 'tiles' referenced before assignment

现在,发生这种情况是因为图块实际上是在 global 空间中定义的。所以,你的函数应该是这样的:

def foobar(in_file, out_file, expression):
    global tiles
    ...

【讨论】:

  • 您可能应该解释它的发生,因为tiles 是在函数中本地定义的,这意味着除非您使用global 关键字,否则任何全局变量都将被忽略。即使您没有全局定义tiles,也会发生此错误。
  • 您是如何获得 UnboundLocalError 消息的?我得到的只是沉默。
  • except 吞下了异常。如果没有except,您将收到该错误。
【解决方案3】:

这是一个有趣的错误。因此,函数外部有一个模块范围的tiles,并且由于您没有使用global,因此您正在函数内部创建一个新的tiles 变量。这可以。或者它会很好,除了它看起来(当我在交互式 Python 中乱七八糟时)语句的左值(左侧的 tiles)是本地的,使整个语句认为对瓷砖的任何引用都意味着本地一。所以在那个地图结构中,它没有使用模块tites,而是使用本地模块,除了本地模块还不存在。

这可能是 Python 中的一个错误,但可能是预期的。

【讨论】:

  • 不是bug,事实上它定义得很好。全局变量和局部变量是有区别的。在这种情况下,您可以使用 global 关键字。 :)
  • 对,但您认为它会首先使用(据当时所知)全局范围评估右侧,然后创建一个局部变量并分配给它。似乎 Python 会提前扫描以查看是否曾创建过同名的局部变量。
猜你喜欢
  • 2011-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-24
  • 2011-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多