假设我们有两个类Class A
,其中包含一个经常抛出的自定义错误,它是其功能的一部分。
#a.py
class AError(Exception):
"""This exception flags a functional error"""
pass
class A(object):
def work(self):
"""Throws AError when it is tired"""
raise AError() #This exception is raised eventually, business code removed for clarity
Class B
,它使用A类执行某些操作。
#b.py
import a
class B(object):
def make_him_work(self, afected):
try:
afected.work()
except a.AError:
pass #This was expected, here will go some business logic
这很好用,但是当我有不同类型的A时它会成为一个问题。理想情况下,我想完全将A与B分离,所以我可以传递任何满足相同界面的A类,但是我不能由于异常(因为它不是界面本身的一部分)
在C ++中,我将有一个头文件,其中包含我的接口的定义以及具体类将实现的异常。这通常如何在Python中解决?或者说另一种方式,什么是最pythonic的方法?
我认为有以下几种选择:
1。创建具有异常的模块,可能是基类/元类(C ++ / Java方式)
#common.py
class AErrorBase(Exception):
pass
class AIface(object):
def work(self):
raise NotImplemented()
#a.py
import common
class AError(common.AErrorBase):
pass
class A(common.AIface):
def work(self):
"""Throws AError when it is tired"""
raise AError()
#b.py
import common
class B(object):
def make_him_work(self, afected):
try:
afected.work()
except common.AErrorBase:
pass #This was expected
2。将异常作为参数传递
#a.py
class AError(Exception):
pass
class A(object):
def work(self):
"""Throws AError when it is tired"""
raise AError()
#b.py
class B(object):
def make_him_work(self, afected, ex_type):
try:
afected.work()
except ex_type:
pass #This was expected
第3。作为类的属性的异常,因此它成为接口的一部分。
#a.py
class A(object):
def work(self):
"""Throws AError when it is tired"""
raise AError()
class AError(Exception):
pass
#b.py
class B(object):
def make_him_work(self, afected):
try:
afected.work()
except afected.AError:
pass #This was expected
4。不要使用异常,只需返回代码。 !C天回来了!
还有其他选择吗?你有什么更多" pythonic"?
编辑:添加注释以阐明异常的目的。它需要在B
中处理注意:这可能完全是因为我正在接近旧C ++背景的问题,我只想知道当我们有异常时如何在python中应用IoC。随意说我的所有方法都是垃圾,我应该用另一种方式来做
答案 0 :(得分:1)
我的课程看起来像这样:
class A(object):
def can_work(self):
"returns True if an A can work otherwise False (e.g. is an A is tired)"
return ...
def work(self):
assert not self._is_tired, "Test if self.can_work() first!"
...
这样您就可以让A的用户测试他们是否应该使用工作。 断言对于调试很有用,并确保您或其他人不会忘记接口。
B类将使用A如下:
class B(object):
def make_him_work(self, afected):
if afected.can_work():
afected.work()