异常处理中的这种奇怪行为是什么?

alv*_*osg 2 python exception-handling python-2.7

我正在使用python 2.7,但是试图创建一个代码来检查对象是否是与python 3+兼容的basetring的子类.我试图遵循这里建议的方法,并在过程中发现了一个我不理解的行为

如果我做:

def foo():
    try: basestring
    except NameError:
        print "a"
foo()
Run Code Online (Sandbox Code Playgroud)

什么都没发生.

如果我稍微修改那个代码只是在except:

def foo():
    try: basestring
    except NameError:
        print "a"
        basestring=str
foo()
Run Code Online (Sandbox Code Playgroud)

然后打印"a".

我不明白如何向except块添加内容,可以影响异常的触发.

我在函数外检查了相同的代码:

try:
    basestring
except NameError:
    print("a")
    basestring=str
Run Code Online (Sandbox Code Playgroud)

但在这种情况下没有打印出来.

mgi*_*son 5

当你添加basestring = str到函数时,你告诉python basestring应该被视为一个局部变量.然而,在被执行的第一条语句的时候,有与名称的局部变量basestring(只一个全球性的),所以Python会引发一个UnboundLocalError.

由于您的异常处理的UnboundLocalError继承NameError被触发,您将看到a打印.


如果你对这个细节感兴趣 - 我们可以使用dis以下方法将其分开:

import dis

def foo():
    try:
        basestring
    except NameError:
        print("a")
        basestring=str

def bar():
    try:
        basestring
    except NameError:
        print("a")

dis.dis(foo)
print('--' * 20)
dis.dis(bar)
Run Code Online (Sandbox Code Playgroud)

请注意,for foo,basestring使用LOAD_FAST操作代码检索(这意味着它正在查找本地变量).在bar然而,basestring使用检索到的LOAD_GLOBAL操作码.