exception not getting caught when not in the right package in python
EDIT: OK, I managed to isolate the bug and the exact, complete code to to reproduce it. But it appears either something that's by design, or a bug in python.
Create two sibling packages: admin
& General
, each with it's own __init__.py
, of course.
In the package admin
put the file 'test.py' with the following code:
from General.test02 import run
import RunStoppedException
try:
run()
except RunStoppedException.RunStoppedException,e:
print 'right'
except Exception,e:
print 'this is what i got: %s'%type(e)
and also in admin
put the file 'RunStoppedException.py' with the following code:开发者_如何学运维
class RunStoppedException(Exception):
def __init__(self):
Exception.__init__(self)
In the package General
put the file test02.py with the code:
import admin.RunStoppedException
def run():
raise admin.RunStoppedException.RunStoppedException()
the printout:
this is what i got: <class 'admin.RunStoppedException.RunStoppedException'>
When it should've been right
. This only happens when one file sits in the same dir as the exception, so they import it differently.
Is this by design, or a bug of python?
I am using python2.6, running it under eclipse+pydev
import admin.RunStoppedException
This is an ambiguous relative import. Do you mean RunStoppedException
from the admin
top-level module? Or from mypackage.admin
when you're in a package? If your current working directory (which is added to the module search path) happens to be inside the package, it could be either, depending on whether Python knows it's inside a package, which depends on how you're running the script.
If you've got both import admin.RunStoppedException
and import RunStoppedException
in different modules, that could very well import two copies of the same module: a top-level RunStoppedException
and a submodule admin.RunStoppedException
of the package admin
, resulting in two instances of the exception, and the subsequent mismatch in except
.
So don't use implicit relative imports. They are in any case going away (see PEP328). Always spell out the full module name, eg. import mypackage.admin.RunStoppedException
. However avoid using the same identifier for your module name and your class name as this is terribly confusing. Note that Python will allow you to say:
except RunStoppedException:
where that identifier is referring to a module and not a subclass of Exception. This is for historical reasons and may also go away, but for the meantime it can hide bugs. A common pattern would be to use mypackage.exceptions
to hold many exceptions. One-class-per-file is a Java habit that is frowned on in Python.
It's also a good idea generally try to keep the importing of module contents (like classes) down as much as possible. If something changes the copy of RunStoppedException
inside the module, you'll now have different copies in different scripts. Though classes mostly don't change, module-level variables may, and monkey-patching and reloading become much harder when you're taking stuff outside of its owner module.
I can only see two reasons
You have two different Exception classes with same name
Edit: I think culprit is this part because you import Exception class two ways- from RunStoppedException import RunStoppedException
- from admin.RunStoppedException import RunStoppedException
make them consistent and your problem will be gone.
You are using some IDE, which is interfering with your code, this sounds bizarre but try to run your code on command line if you aren't
Even 1 and 2 doesn't fix your problem, write a small piece of code demonstrating the problem, which we can run here, which we can fix, but I am sure we will not need to because once you have written such a small standalone script where you can replicate the problem you will find the solution too.
Works fine for me:
[/tmp] ls admin/
RunStoppedException.py __init__.py test.py
RunStoppedException.pyc __init__.pyc
[/tmp] ls General/
__init__.py __init__.pyc test02.py test02.pyc
[/tmp] python -m admin.test
right
[/tmp]
Running on:
Python 2.6.4 Stackless 3.1b3 060516 (release26-maint, Dec 14 2009, 23:28:06)
[GCC 4.2.1 (Apple Inc. build 5646) (dot 1)] on darwin
My guess is that you have another "General" on your path somewhere, perhaps from earlier tests, and thats why the exceptions don't match.
Did you try the id
/inspect.getabsfile
debugging? If so, what was the output?
精彩评论