首页 > 解决方案 > 如何在 Python 类中继承错误处理

问题描述

我正在编写一些样板代码,其中有一些其他人将从中继承的抽象类。并非每个方法都需要运行,因此抽象类使用 @handleError 作为装饰器来处理异常。

我会用狗来说明(实际问题要复杂得多)

  1. 这是异常处理装饰器(如果无法运行,则返回无)
def handleError(f):
    def handleProblems(*args, **kwargs):
        try:
            return f(*args, **kwargs)
        except Exception:
            return None
    return handleProblems
  1. 动物类,将继承自
class Animal:
    def __init__(self, eat_time, animal_sound):
        self.sound = animal_sound
        self.eat_time = eat_time

    @handleError  # <-- if the user messes up "eat", keep going! 
    def eat(self):
        print('Eats for %0.0f seconds' % self.eat_time)    

    def speak(self):
        print(self.sound)

    def eat_and_speak(self):
        self.eat()
        self.speak()

  1. 所以现在“好狗”和“坏狗”都跑到最后了。(当然,“坏狗”只会说“汪”)
# good dog
dog = Animal(4, 'woof')
dog.eat_and_speak()

# messed up dog
dog = Animal('four', 'woof')
dog.eat_and_speak()

> 'Eats for 4 seconds'
> 'woof'  
> 'woof' . # <-- yay! the messed up dog barked! 

这正是我们想要的,但我们也希望允许用户继承。例如,通过这样做:

class Dog(Animal):
    def eat(self):
        print('Dog eats for %0.0f seconds' % self.eat_time)

但是,唉,现在只允许好狗:

# good dog
dog = Dog(4, 'woof')
dog.eat_and_speak()  # <-- works fine 

# bad dog 
dog = Dog('four', 'woof')
dog.eat_and_speak()  # <-- raises ValueError (as 'four' isn't float)

bad dog 引发了一个值错误,因为它不再有装饰器。

解决此问题的一种方法是使用带有装饰器的私有方法:

class Animal:
    def __init__(self, eat_time, animal_sound):
        self.sound = animal_sound
        self.eat_time = eat_time

    def eat(self):
        print('Eats for %0.0f seconds' % self.eat_time)

    def speak(self):
        print(self.sound)

    @handleError
    def _eat(self):
        self.eat()

    def eat_and_speak(self):
        self._eat()
        self.speak()

现在允许以下坏狗处理异常:

class Dog(Animal):
    def eat(self):
        print('Dog eats for %0.0f seconds' % self.eat_time)

dog = Dog('four', 'woof')
dog.eat_and_speak()
> 'woof'

然而,这看起来很笨拙和丑陋。

问题:类从抽象类继承错误处理的最佳方式是什么?

注意:真正的用例是一些爬虫样板代码,其中一些方法预计会出错,但爬虫应该在返回 None 时继续运行。各个刮板的所有者将从这个类继承,希望它会为他们处理这个问题。

标签: pythonclassinheritanceabstract-class

解决方案


推荐阅读