tags:

views:

103

answers:

2

Hi all. I noticed something weird today I would like explained. I wasn't 100% sure how to even phrase this as a question, so google is out of the question. The logging module does not have access to the module logging.handlers for some odd reason. Try it yourself if you don't believe me:

>>> import logging
>>> logging.handlers
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'handlers'
>>> import logging.handlers
>>> logging.handlers
<module 'logging.handlers' from '/usr/lib/python2.6/logging/handlers.pyc'>

Can anyone explain why this happens?

+14  A: 

In Python, modules need to be imported before they're accessible. import logging imports just the logging module. It so happens that logging is a package with submodules, but those submodules are still not automatically loaded. So, you need to explicitly import logging.handlers before you can access it.

If you're wondering why it looks like sometimes you don't need those extra imports: some packages import some or all of their submodules when they are imported -- simply by doing those imports in their __init__.py files. In other cases it might be that something else that you import, also imported logging.handlers. It doesn't matter which piece of code does the import; as long as something in your process imports logging.handlers before you access it, it'll be there. And sometimes a module that looks like a package really isn't one, like os and os.path. os isn't a package, it just imports the correct other module (for your platform) and calls it path, just so you can access it as os.path.

Thomas Wouters
A: 

I'm also new to python and after having lots of practice now I can differentiate between, package (folder) , module(.py) , classes,variables...etc...

if you want any of your folder to be python package - It must contain __init__.py file even empty file will do !!!

and as Thomas said, you can import extra module in __init__.py if you want !!! but modules/packages are accessible only after importing it...

if you want to import everything from a module you can use

from logging import *

rest you can access the handlers module like below too,

from loggin import handlers
print dir(handlers)
Tumbleweed
Please do not use `from module import *`. It's almost always a mistake.
Thomas Wouters
@Thomas Wouters: Yes I know its bad practice but some times it helps when we've defined `__all__` variable on `__init__.py` of package
Tumbleweed
If you want everything in a package to be imported automatically, do those imports in __init__.py, instead of setting __all__ in __init__.py and doing 'from package import *' somewhere.
Thomas Wouters
yes, you're right!
Tumbleweed
`from module import *` isn't ALWAYS a mistake, though 99.9% of the time it is at least with built-in modules. There are a couple of modules that I use that require wildcard importing because they define a lot of constants that need to be used.
Falmarri
Someone please explain why 'from module import *' is problematic
Pete
@Pete: because it "pollutes" the standard namespace which leads to ambiguity and conflict. If I had `import zipper` and `zipper.open()` you'd know exactly which open I was calling. Contrariwise `from zipper import *` followed by `open()` is it the built-in open or zipper.open or something else. `import zipper as z` is much preferred if you get tired of typing `zipper`
msw
@Pete: It's also a problem because you might overwrite some of your namespace unknowingly. I used to use from `numpy import *` because some numpy functions don't work unless you import all of numpy (terrible design flaw on their part IMO) but numpy has a HUGE number of objects that it imports. I ended up overwriting a lot of functions (I believe copy was one... I'm too tired to check). Now I do import numpy as np if I'm going to use numpy so much that I can't stand to type it over and over.
dustynachos