【问题标题】:python custom exception handler for a class一个类的python自定义异常处理程序
【发布时间】:2014-02-18 12:21:54
【问题描述】:

我想用 redis 缓存构建我的应用程序。但在我们的案例中,redis 可能并非一直可用,
所以我希望,它 redis 运行良好,我们使用它。如果它不能工作,只需记录并这次忽略它。

例如:

尝试: conn.sadd('s', *array) 除了 : ...

因为有很多地方我会运行一些 conn.{rediscommand},我不喜欢在每个地方都使用 try/except。

所以解决方案可能:

类软缓存(redis.StrictRedis): def 悲伤(键,* p): 尝试: super(redis.StrictRedis, self).sadd(key, p) 除了: ..

但是由于redis有很多命令,所以我得一个一个地扭曲它们。

是否可以为一个类自定义一个异常处理程序来处理来自该类的所有异常?

【问题讨论】:

  • 看看Exceptions for the whole class。您可以按照建议使用装饰器或调度器。
  • 语法是try: ... except: ...
  • 这就是context managers 的用途。
  • @Bakuriu 上下文管理器的问题是每次执行函数调用时都必须编写with 块。我认为包装器/代理会更有用(在捕获所有内容的错误内......)
  • @ikaros45 我认为这不是问题。如果函数是在库中定义的,您想要修改它只是为了避免键入with。如果其他人阅读您的代码,他将无法理解到底发生了什么。 如果函数是你自己定义的,那么使用装饰器添加异常处理肯定会更好。

标签: python exception


【解决方案1】:

默认情况下使所有异常静音可能是您能做的最糟糕的事情。

无论如何,对于您的问题,您可以编写一个仅重定向到连接对象的通用包装器。

class ReddisWrapper(object):

    conn = conn # Here your reddis object

    def __getattr__(self, attr):

         def wrapper(*args, **kwargs):
             # Get the real reddis function
             fn = getattr(self.conn, attr)

             # Execute the function catching exceptions
             try:
                  return fn(*args, **kwargs)

             # Specify here the exceptions you expect                 
             except:
                  log(...)

         return wrapper

然后你会这样调用:

reddis = ReddisWrapper()
reddis.do_something(4)

这尚未经过测试,仅适用于方法。对于属性,您应该捕获不可调用的异常并做出正确的反应。

【讨论】:

  • 嗨 ikaros45,我最容易理解您的建议。但似乎不起作用。 ` class X(object): def p(self, a): print(a) raise '1' class WX(object): x = X() def __getattr__(self, item, *args, **kwargs): print args fn = getattr(self.x, item) print("fn", fn) try: fn(args) except: print("get Exception") wx = WX() wx.p('abc') print "ok " `
  • 嗨 ikaros45,感谢您的建议。它现在可以使用以下代码。 def __getattr__(self, attr): if hasattr(self.__conn, attr): def wapper(*args, **kw): fn = getattr(self.__conn, attr) try: return fn(*args, **kw ) 除了 redis.exceptions.ConnectionError: pass return wapper raise AttributeError()
  • 您能否修改您的答案,以便我接受您的答案。我从你的建议中学到了很多。谢谢!
  • @zhihuifan,我很乐意提供帮助,但我不明白您在 cmets 中发布的代码。
  • 如果你尝试你的建议,你会发现 getattr 只接受 2 个参数,而不是 4 个。在我的评论中,getattr 返回一个指向函数的指针wapper,wapper 接受这些参数,就行了。
【解决方案2】:

总是一样的Exception

如果是这样,您可以编写自定义的异常捕获和日志装饰器。

类似于以下内容:

def exception_catcher(fn):
    try:
        fn()
    except Exception as e:
        log(e)

然后在你的代码周围使用它:

@exception_catcher
sadd('s', *array)

@idanshmu 建议的Exceptions for the whole class 的评论和链接将提供对每个方法的不同Exceptions 的更详细处理。

【讨论】:

  • 嗨伊万,这不是同一个例外。顺便说一句,我在哪里可以找到@xxxx python 支持的完整列表?
  • 嗨伊万,应该是同样的例外。现在明白你的建议了。谢谢!
猜你喜欢
  • 1970-01-01
  • 2019-07-15
  • 2011-07-13
  • 2015-10-18
  • 2023-03-04
  • 1970-01-01
  • 2015-12-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多