python - 如何在 Python 类中继承错误处理
问题描述
我正在编写一些样板代码,其中有一些其他人将从中继承的抽象类。并非每个方法都需要运行,因此抽象类使用 @handleError 作为装饰器来处理异常。
我会用狗来说明(实际问题要复杂得多)
- 这是异常处理装饰器(如果无法运行,则返回无)
def handleError(f):
def handleProblems(*args, **kwargs):
try:
return f(*args, **kwargs)
except Exception:
return None
return handleProblems
- 动物类,将继承自
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()
- 所以现在“好狗”和“坏狗”都跑到最后了。(当然,“坏狗”只会说“汪”)
# 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 时继续运行。各个刮板的所有者将从这个类继承,希望它会为他们处理这个问题。
解决方案
推荐阅读
- javascript - 如何从创建的 div 中删除我创建的 div?
- csv - 将一个csv文件拆分为多个文件
- javascript - 加载时如何将数据加载到其他网站的文本区域
- javascript - 根据对象是否包含详细属性过滤对象
- angular - 测试组件正在使用原始服务而不是监视它
- cucumber - “如何在黄瓜中的某些特定场景之前用 5 个步骤执行整个场景”
- c# - LoadScene 始终在编辑器中有效,但仅在 Build: Unity 中首次播放时有效
- java - 为什么 Maven 使用提供的构建插件的 pom.xml?
- java - 如何使用 api Graphstream 在 android studio 中通过触摸创建节点?
- gtk - monodevelop gtk-sharp 中的 MDI 形式