"from module import data; print(data)" vs "import module; print(module.data)"

Ben Finney ben+python at benfinney.id.au
Thu Feb 25 23:37:14 EST 2016

Steven D'Aprano <steve at pearwood.info> writes:

> On Fri, 26 Feb 2016 10:38 am, Ben Finney wrote:
> > Gregory Ewing <greg.ewing at canterbury.ac.nz> writes:
> > 
> >> sohcahtoa82 at gmail.com wrote:
> >> > Now, I've noticed people talking about importing os.path.  Is there any
> >> > reason to use "import os.path" rather than "import os"?  Both of them
> >> > will still put the "os" module into the global namespace.
> >>
> >> In the case of os.path it doesn't matter, because the
> >> os module imports the appropriate path module automatically.
> > 
> > My position is that behaviour violates one of the principles of the Zen
> > of Python: “Special cases aren't special enough to break the rules.”
> But it's not special. It's the standard behaviour of any module which offers
> a public name

That is the special behaviour. ‘os’ is a package that has a sub-module
‘path’. Normally, to get at a module inside a package, you import it
with a qualified name::

    import os.path

The special case is that ‘os’ also wants the ‘path’ module itself, and
so the name happens to be available as a module attribute. That's a
special case that can not be depended on for other cases.

> `import os` makes all the names in the os name space available.

Since ‘os.path’ is a sub-module of the ‘os’ package, it should not also
be exported from the ‘os’ module attributes. The special case is confusing.

> There's no difference between (say) `os.listdir` and `os.path` except
> that listdir happens to be a function and path happens to be a module.

There's no difference between ‘logging.info’ and ‘logging.config’ except
that ‘info’ happens to be a function and ‘config’ happens to be a

The difference is salient::

    >>> import logging
    >>> logging.info
    <function info at 0x7fa7935bfa60>
    >>> logging.config
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: module 'logging' has no attribute 'config'

That's the case normally, when one name is primarily an attribute and
another name is primarily a sub-module. The ‘os.path’ case is not
special enough to break that rule IMO.

> `path` has been a documented public attribute of the `os` module since at
> least Python 1.5:

Then it's been violating that principle for that long :-)

> If you take "Special cases are not special enough" seriously, you will
> not use `import os.path` since os is not a package

The implementation is special. That doesn't exempt it from the principle
that a special case isn't special enough to break expectations.

> and os.path is not part of os, it's just a publicly exposed attribute
> which merely happens to be a module.

You seem to be making my case for me: ‘os’ is indeed special. It goes to
some legth to hide that specialness; I think it doesn't go far enough.

 \         “If you don't want your beliefs to be ridiculed, don't have |
  `\            such ridiculous beliefs.” —Greta Christina, 2011-10-22 |
_o__)                                                                  |
Ben Finney

More information about the Python-list mailing list