2

New python user (2.7.5).

Trying to implement a simple exception. Exception-derived classes are taking string input arguments and splitting them into individual characters.

I've looked around for about 90 minutes in the tutorial and on stackoverflow and haven't found an answer.

# Meaningless base class.
class base:
    def __init__(self):
        self.base = 1

# Somewhat useful test of string storage.
class test(base):
    def __init__(self, arg):
        self.args = arg

This yields:

>>> a = test('test')
>>> a.args
'test'

But when I try:

# No qualitative difference between this and the above definition,
# except for 'Exception'.
class test(Exception):
    def __init__(self, arg):
        self.args = arg

I get:

>>> a = test('test')
>>> a.args
('t', 'e', 's', 't')

The only change is in class inheritance.

I would like to have my strings in one piece in my exception class so I can actually print and read them. What is happening?

1
  • Actually it doesnt work the way you told for me. I get the value of x.args as "test" [a string]. I dont know what your problem is Commented Jun 11, 2013 at 15:43

2 Answers 2

4

The Exception class makes args a property (data descriptor) with this setter:

static int
BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)
{
    PyObject *seq;
    if (val == NULL) {
        PyErr_SetString(PyExc_TypeError, "args may not be deleted");
        return -1;
    }
    seq = PySequence_Tuple(val);
    if (!seq) return -1;
    Py_CLEAR(self->args);
    self->args = seq;
    return 0;
}

The line

seq = PySequence_Tuple(val);

turns the value into a tuple.

So in your Python code,

    self.args = arg

triggers the setter and causes self.args to be set to a tuple.

Sign up to request clarification or add additional context in comments.

2 Comments

Am I to understand the init for BaseException is called? And how does one escape underscores here?
@user2475059: Python has a complicated set of attribute lookup rules. Those rules allow base classes to define data descriptors which alter the way self.args = args behaves. It has nothing to do with BaseException.__init__ getting called (it doesn't). To escape underscores, surround the string with backticks (`).
4

I haven't made many user-defined exceptions myself, but I get the impression that the self.args = arg statement is triggering a property setter that converts arg to a tuple (tuple('test') results in ('t', 'e', 's', 't')). (And it seems I was right, according to unutbu). Two things you could try:

class test(Exception):
    def __init__(self, arg):
        self.args = (arg,)

or

class test(Exception):
    def __init__(self, *args):
        self.args = args

Either one of those should resolve the problem, but I'd recommend the second one as it's more Pythonic. Some examples of how this works, using Exception itself:

>>> a = ['abc', 'def']
>>> Exception(a)
Exception(['abc', 'def'],)
>>> Exception(*a)
Exception('abc', 'def')

4 Comments

If I do that and replace a.args with a.args[0], it'll give me what I want. I would like to understand the difference, though, since I have no idea what you're talking about or why the code isn't behaving the way the tutorial says it should. Is there a module where the Exception class is defined that I can read?
@user2475059 If you have no idea what I'm talking about, then you need to relearn Python (or at least read through the main Python tutorial [docs.python.org/tutorial/index.html]). Properties and argument lists are two very useful features provided by Python, and argument lists (or at least the ability to unpack iterables as such) are used in many Python programs.
I specified 2.7.5. The tutorial says it's for 2.7.5. I don't remember seeing anything about properties or argument lists in the tutorial, but it's been a while since I last read it closely.
@user2475059 Yeah, I noticed that after I made the Python 2/3 comment so deleted that. Personally, I recommend using the tutorial available from the Python documentation that I linked; it's the one I used when I first started Python and it was very useful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.