Reputation: 894
I have two files. One is program_utils.py
with the contents:
class SomeException(Exception):
def __init__(self, *args, **kwargs):
Exception.__init__(self, *args, **kwargs)
another, say, program.py
, with
import program_utils
def SomeFunction(arg):
if arg in set([ok_val1, ok_val2]):
# do something
else:
raise SomeException('reason')
When I run program.py
it complains: NameError: name 'MyException' is not defined
. When I paste the contents of program_utils.py
directly into program.py
, it works fine. Why?
Upvotes: 0
Views: 54
Reputation: 2833
Unlike #include
in C
/C++
, in python the import
statement is not equivalent to copy/pasting the file into your file.
If you want that behavior, you can sort of get it by doing:
from program_utils import *
However, there are some caveats. e.g.: if you are importing a package, the __all__
variable in the __init__.py
controls which symbols get imported whtin doing from foo import *
.
In general, from foo import *
is not a very good practice. You don't necessarily know what symbols you are importing. Additionally you may overwrite the value of some symbols if you do that with more than one module and they both define the same symbol(s).
Arguably it is also somewhat more clear what is going on if you use the module name when using its symbols. i.e.:
foo.bar()
vs
from foo import *
...
from spam import *
bar()
In the second case it might not be obvious that bar
came from the foo module.
There is a (small) performance consideration. If you end up doing foo.bar()
a lot, you are actually doing an unnecessary dictionary lookup because every time, the interpreter looks up 'bar'
in foo.__dict__
. To fix that, you can do:
from foo import bar
Upvotes: 2