Python 2.7 からリモート XML ベースの API をラップしています。API は、<statusCode>
要素だけでなく要素も送信することでエラーをスローし<statusDescription>
ます。現時点では、この条件をキャッチして、単一の例外タイプを発生させます。何かのようなもの:
class ApiError(Exception):
pass
def process_response(response):
if not response.success:
raise ApiError(response.statusDescription)
これは問題なく動作しますが、より洗練された方法でエラーを処理したいと考えています。要素があるのでstatusCode
、statusCode に基づいて ApiError の特定のサブクラスを発生させたいと思います。事実上、ラッパーを次のように拡張したいと考えています。
class ApiError(Exception):
def __init__(self, description, code):
# How do I change self to be a different type?
if code == 123:
return NotFoundError(description, code)
elif code == 456:
return NotWorkingError(description, code)
class NotFoundError(ApiError):
pass
class NotWorkingError(ApiError):
pass
def process_response(response):
if not response.success:
raise ApiError(response.statusDescription, response.statusCode)
def uses_the_api():
try:
response = call_remote_api()
except NotFoundError, e:
handle_not_found(e)
except NotWorkingError, e:
handle_not_working(e)
特定の を特定のサブクラスに結び付けるstatusCode
仕組みは簡単です。しかし、私が望むのは、それが ApiError のどこかに埋め込まれていることです。具体的には、値を渡す以外に process_response を変更したくありませんstatusCode
。
私はメタクラスを見てきましたが、__new__
実行時の引数ではなく書き込み時の引数を取得するため、メタクラスが状況に役立つかどうかはわかりません。__init__
同様に、インスタンスを返すことを意図していないため、ハッキングも役に立ちません。では、渡された引数に基づいて特定のサブクラスをインスタンス化するにはどうすればよい__init__
でしょうか?