我有一个基本的“最佳实践”Python问题。我看到已经有与此问题相关的StackOverflow答案,但是他们陷入了复杂的例子或涉及多个因素。
鉴于此代码:
#!/usr/bin/python
def test_function():
try:
a = str(5)
raise
b = str(6)
except:
print b
test_function()
什么是避免不可避免的“UnboundLocalError:在赋值之前引用的局部变量'b'的最佳方法”我将在异常处理程序中获取?
python是否有一种优雅的方式来处理这个问题?如果不是,那么一种不优雅的方式呢?在一个复杂的函数中,我宁愿在我之前避免测试每个局部变量的存在,例如,打印关于它们的调试信息。
答案 0 :(得分:10)
python是否有一种优雅的方式 处理这个?
为避免打印未绑定名称的异常,最优雅的方法是不打印它们;第二个最优雅的是确保名称受到限制,例如通过在函数的开头绑定它们(占位符None
很受欢迎)。
如果没有,那么一种不雅的方式呢?
try: print 'b is', b
except NameError: print 'b is not bound'
在一个复杂的功能中,我更喜欢 避免测试存在 我之前的每个局部变量 例如,打印调试信息 关于他们
强烈建议您保持简单的功能(即不复杂)。正如Hoare在30年前写的那样(在他的图灵接受演讲“皇帝的旧衣服”中,例如在this PDF中重印):
有两种构建方式 软件设计:一种方法是制作它 如此简单,显然没有 缺点,另一种方式是 让它变得如此复杂以至于有 没有明显的缺陷。首先 方法要困难得多。
实现和维护简单 确实很难:鉴于你必须实现一定的全部功能X,这是世界上最自然的诱惑,通过复杂的增加到一些复杂的类和各种零碎的功能,“聪明”的黑客,复制粘贴和编辑“驱动编码”等剧集等。
但是,努力保持你的功能“如此简单以至于显然没有缺陷”是值得的。如果一个函数难以完全单元测试,那就太复杂了:将它分解(即重构它)成为它的自然组件,即使它需要工作来挖掘它们。 (这实际上是强调单元测试有助于提高代码质量的方法之一:通过不断激励您保持所有代码完全可测试,同时促使您简化它的结构)。
答案 1 :(得分:6)
您可以在try块
之外初始化变量a = None
b = None
try:
a = str(5)
raise
b = str(6)
except:
print b
答案 2 :(得分:2)
您可以使用内置方法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()
答案 3 :(得分:1)
def test_function():
try:
a = str(5)
raise
b = str(6)
except:
print b
b = str(6)
永远不会运行;程序在try
之后退出raise
块。如果要在except
块中打印一些变量,请在引发异常之前对其进行评估,并将它们放入您抛出的异常中。
class MyException(Exception):
def __init__(self, var):
self.var = var
def test_function():
try:
a = str(5)
b = str(6)
raise MyException(b)
except MyException,e:
print e.var