iswbm / magic-python

Python 黑魔法手册
http://magic.iswbm.com/
3.3k stars 478 forks source link

c01/c01_19 #56

Open utterances-bot opened 1 year ago

utterances-bot commented 1 year ago

1.19 return不一定都是函数的终点 — Python黑魔法手册 1.0.0 documentation

https://magic.iswbm.com/c01/c01_19.html

SuperMondot commented 1 year ago

def a(): try: a = '1' b = a * 10 - 5 return b finally: return b

print(a()) print(help('finally'))

来解释一下这个

CoreJK commented 1 year ago

试着执行了楼上的代码,异常信息如下

In [9]: print(a())
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[5], line 4, in a()
      3 a = '1'
----> 4 b = a * 10 - 5
      5 return b

TypeError: unsupported operand type(s) for -: 'str' and 'int'

During handling of the above exception, another exception occurred:

UnboundLocalError                         Traceback (most recent call last)
Cell In[9], line 1
----> 1 print(a())

Cell In[5], line 7, in a()
      5     return b
      6 finally:
----> 7     return b

UnboundLocalError: local variable 'b' referenced before assignment

猜测想表达的意思是如果 try 中的异常字符串异常被触发,变量 b 的值应该被返回。

但是实际上是,a * 10 - 5 的异常被触发后,变量 b 的还没来得及被赋值(严谨说叫引用),解释器已经抛出异常了。所以,接下来到了 finally 代码块中,return 一个不存在的变量,会出现报错 local variable 'b' referenced before assignment

在一楼的代码上修改一下,就能正常执行 finally 语句了

def a():
    try:
        a = '1'
        b = 'finally will get this value'
        b = a * 10 - 5
        return b
    finally:
        return b

执行结果

In [11]: a()
Out[11]: finally will get this value

好像这个还涉及到 “LEGBA” 的变量查找顺序的知识点