Note that there are some explanatory texts on larger screens.

plurals
  1. POHow do I instantiate a specific subclass based on arguments passed to __init__?
    primarykey
    data
    text
    <p>I'm wrapping a remote XML-based API from python 2.7. The API throws errors by sending along a <code>&lt;statusCode&gt;</code> element as well as a <code>&lt;statusDescription&gt;</code> element. Right now, I catch this condition and raise a single exception type. Something like:</p> <pre><code>class ApiError(Exception): pass def process_response(response): if not response.success: raise ApiError(response.statusDescription) </code></pre> <p>This works fine, except I now want to handle errors in a more sophisticated fashion. Since I have the <code>statusCode</code> element, I would like to raise a specific subclass of ApiError based on the statusCode. Effectively, I want my wrapper to be extended like this:</p> <pre><code>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) </code></pre> <p>The machinery for tying specific <code>statusCode</code>'s to specific subclasses is straightforward. But what I want is for that to be buried inside of ApiError somewhere. Specifically, I don't want to change process_response except to pass in the value <code>statusCode</code>.</p> <p>I've looked at metaclasses, but not sure they help the situation, since <code>__new__</code> gets write-time arguments, not run-time arguments. Similarly unhelpful is hacking around <code>__init__</code> since it isn't intended to return an instance. So, how do I instantiate a specific subclass based on arguments passed to <code>__init__</code>?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload