如何在Python的Try/Catch块中捕获所有异常?

8

我正在编写Python代码,在Linux环境中安装程序所需的所有库包。因此,Linux可能包含Python 2.7或2.6或两者都有,所以我开发了一个try和except块的代码,用于在Linux上安装pip包。Try块代码包含Python 2.7版本的pip install,Catch块包含Python 2.6版本的pip install。我的问题是,当我尝试在Python 2.6中安装pandas时,它会给我带来一些错误。我想捕获该异常。请告诉我如何改进我的try except块以捕获该异常。

required_libraries = ['pytz','requests','pandas']
try:
   from subprocess import check_output
   pip27_path = subprocess.check_output(['sudo','find','/','-name','pip2.7'])
   lib_installs = [subprocess.call((['sudo',pip27_path.replace('\n',''),'install', i])) for i in required_libraries]
except:
   p = subprocess.Popen(['sudo','find','/','-name','pip2.6'], stdout=subprocess.PIPE);pip26_path, err = p.communicate()
   lib_installs = [subprocess.call((['sudo',pip26_path.replace('\n',''),'install', i])) for i in required_libraries]

在你已经有的 except 块中再放一个 try: except: 块? - Chris Charles
@ChrisCharles 刚刚我尝试了相同的方法,仍然无法捕获异常。 - Rahul
@ChrisCharles 除非: 尝试: p = subprocess.Popen(['sudo','find','/','-name','pip2.6'], stdout=subprocess.PIPE);pip26_path, err = p.communicate() lib_installs = [subprocess.call((['sudo',pip26_path.replace('\n',''),'install', i])) for i in required_libraries] except Exception as e: logging.info("pip_installs函数中出现错误 '%s'" %e) - Rahul
1
捕获所有异常通常是一个糟糕的想法。请参见https://dev59.com/kWkv5IYBdhLWcg3wbgbQ - tripleee
1个回答

19

您可以使用一个代码块捕获多个异常。让我们使用Exception和ArithmeticError来处理异常。

try:
    # Do something
    print(q)

# Catch exceptions  
except (Exception, ArithmeticError) as e:
    template = "An exception of type {0} occurred. Arguments:\n{1!r}"
    message = template.format(type(e).__name__, e.args)
    print (message)
如果需要捕获多个异常并对每个异常单独处理,则需要为每个异常编写一个except语句。
try:
    # Do something
    print(q)

# Catch exceptions  
except Exception as e:
    print (1)

except ArithmeticError as e:
    print (2)

# Code to be executed if the try clause succeeded with no errors or no return/continue/break statement

else:
    print (3)

您还可以使用if语句检查异常是否属于特定类型,例如“MyCustomException”类型。

if isinstance(e, MyCustomException):
    # Do something
    print(1)

针对您的问题,我建议将代码拆分成两个函数。

install(required_libraries)

def install(required_libraries, version='pip2.7'):
    # Perform installation
    try:
        from subprocess import check_output
        pip27_path = subprocess.check_output(['sudo','find','/','-name', version])
        lib_installs = [subprocess.call((['sudo',pip27_path.replace('\n',''),'install', i])) for i in required_libraries]

    except Exception as e:
        backup(required_libraries)

def backup(required_libraries, version='pip2.6'):
    try:
        p = subprocess.Popen(['sudo','find','/','-name',version]], stdout=subprocess.PIPE);pip26_path, err = p.communicate()
        lib_installs = [subprocess.call((['sudo',pip26_path.replace('\n',''),'install', i])) for i in required_libraries]

    except Exception as e:
        template = "An exception of type {0} occurred. Arguments:\n{1!r}"
        message = template.format(type(e).__name__, e.args)
        print (message)

        #Handle exception

注意:我没有测试过这个,而且我也不是专家,所以希望我能帮到你。

有用的链接:

  1. 内置异常
  2. 错误和异常
  3. 复合语句

非常感谢您的回复。我会检查哪一个最适合这段代码。 - Rahul
@Rahul,如果我的建议有用,请接受答案!祝你好运! - mrhallak
@当然,我会做到。 - Rahul
2
第二个代码块中关于try-except-else块中'else'的目的的注释"If it's an exception but it's none of the above"是不正确的。事实上,只有在'try'中没有引发任何异常的情况下才会执行'else'套件中的代码。请参阅Python文档:"如果控制流离开try套件,没有引发异常,并且没有执行return、continue或break语句,则执行可选的else子句。" - Matt P
@MattP 感谢您的澄清,我已经更新了我的帖子。 - mrhallak
except Exception as e:并不能真正捕获所有异常。 - Charlie Parker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接