基本Python:异常抛出与局部变量作用域/绑定
我有一个关于Python的基本“最佳实践”的问题。我看到已经有一些与这个问题相关的StackOverflow回答,但它们都涉及复杂的例子或者多个因素,让人看得很困惑。
给定这段代码:
#!/usr/bin/python
def test_function():
try:
a = str(5)
raise
b = str(6)
except:
print b
test_function()
有什么好的方法可以避免在异常处理器中出现“UnboundLocalError: local variable 'b' referenced before assignment”的错误呢?
Python有没有简单优雅的方式来处理这个问题?如果没有,那有没有什么不那么优雅的方法?在一个复杂的函数中,我希望能避免在打印调试信息之前,检查每个局部变量是否存在。
4 个回答
你可以使用一个内置的方法 locals()
来检查变量是否在本地范围内被定义。
http://docs.python.org/library/functions.html#locals
#!/usr/bin/python
def test_function():
try:
a = str(5)
raise
b = str(6)
except:
if 'b' in locals(): print b
test_function()
你可以在尝试块外面初始化你的变量。
a = None
b = None
try:
a = str(5)
raise
b = str(6)
except:
print b
Python有没有优雅的方法来处理这个问题?
为了避免因为打印未绑定的变量名而出现错误,最优雅的方法就是不打印它们;第二个优雅的方法是确保这些变量名是绑定的,比如在函数开始时给它们赋一个值(通常用None
来表示)。
如果没有,那有没有不优雅的方法呢?
try: print 'b is', b
except NameError: print 'b is not bound'
在一个复杂的函数中,我更倾向于避免在打印调试信息之前,检查每个局部变量是否存在。
保持函数简单(也就是不要复杂)是非常推荐的。正如霍尔在30年前的图灵奖演讲《皇帝的新衣》中所说(可以在这个PDF中找到):
构建软件设计有两种方式:一种是让它简单到显然没有缺陷,另一种是让它复杂到没有明显的缺陷。第一种方法要困难得多。
实现和保持简单确实很难:当你需要实现某个完整功能X时,最自然的诱惑就是通过把各种复杂的类和函数拼凑在一起,使用一些“聪明”的技巧,或者复制粘贴稍微修改一下的方式来完成。
然而,努力保持你的函数“简单到显然没有缺陷”是值得的。如果一个函数很难完全进行单元测试,那说明它太复杂了:你需要把它拆分成更自然的组成部分,尽管这需要一些工作来发现它们。(这实际上是专注于单元测试提高代码质量的一种方式:它不断促使你保持所有代码都能完美测试,同时也促使你让结构简单)。