Reputation: 133
My code:
class AError(Exception):
print 'error occur'
for i in range(3):
try:
print '---oo'
raise AError
except AError:
print 'get AError'
else:
print 'going on'
finally:
print 'finally'
When I run the above code, the output is this:
error occur
---oo
get AError
finally
---oo
get AError
finally
---oo
get AError
finally
I think the string "error occur"
should occur three times, like "---oo"
, but it only occurs once; why?
Upvotes: 9
Views: 977
Reputation:
I strongly recommend not to place any print statements in your Exception, esp. not their constructors! Exceptions are semantic entities and you can print them out if you need to. If you must automate the printing at least use logging
or a similar package.
What you might not be aware of is that you can collect the exception instance for use in the except
clause like so:
class MyError(Exception):
pass
for i in range(3):
try:
print '---oo'
raise MyError("error msg no. {}".format(i))
# Exception usually always accept a string as their first parameter
except MyError, ex:
# Exception instance available inside the except clause as `ex`
print ex
else:
print 'going on'
finally:
print 'finally'
Upvotes: 2
Reputation: 122152
To clarify Paul's answer, here's a simple example:
class Test(object):
print "Class being defined"
def __init__(self):
print "Instance being created"
for _ in range(3):
t = Test()
The output from this will be:
Class being defined
Instance being created
Instance being created
Instance being created
Code within the class
definition but outside a method def
inition runs only once, when the class is defined.
If you want code to run whenever an instance is created, it should be in the __init__
instance method (or, occasionally, the __new__
class method). However, note that if you define __init__
for a subclass, you should probably ensure that it also calls the superclass's __init__
:
class AError(Exception):
def __init__(self, *args, **kwargs):
Exception.__init__(self, *args, **kwargs) # call the superclass
print 'error occur' # print your message
This ensures that the subclass supports the arguments for the superclass; in the case of Exception
, you can e.g. pass an error message:
>>> raise AError("Something went wrong.")
error occur # your message gets printed when the instance is created
Traceback (most recent call last):
File "<pyshell#11>", line 1, in <module>
raise AError("Something went wrong.")
AError: Something went wrong. # the error message passes through to the traceback
For an explanation of the *args, **kwargs
syntax, if you aren't familiar with it, see e.g. What does ** (double star) and * (star) do for parameters?. You can also use super
to call the superclass methods, see e.g. Understanding Python super() with __init__() methods.
Upvotes: 11
Reputation: 21
The 'error occur'
string appears only one because Python executes it when parsing your AError
class definition.
If you want to get it executed every time you create an instance of your class, you must define the class's initialiser:
class AError(Exception):
def __init__(self):
print 'error occur'
for i in range(3):
try:
print '---oo'
raise AError
except AError:
print 'get AError'
else:
print 'going on'
finally:
print 'finally'
Have fun (and read the language manual maybe...)
Upvotes: 1
Reputation: 83411
'error occur'
only gets printed once, for the entire class.
You probably expected it to get run for each instance of the class that was created.
For that to happen, put it in the __init__
function,
class AError(Exception):
def __init__(self):
print 'error occur'
__init__
is called when an instance of AError
is created.
Upvotes: 5