import in Python3.3

F

Fabian von Romberg

Hi,

I have a package name collections and inside of my package I want to import the collections package from the standard library, but there is name conflicts.

How do I import explicitly from the standard library?

Im working on Python3.3

Thanks in advance and regards,
Fabian
 
S

Steven D'Aprano

Hi,

I have a package name collections and inside of my package I want to
import the collections package from the standard library, but there is
name conflicts.

How do I import explicitly from the standard library?

You can't. However, you can import explicitly from your package, or
implicitly by using a relative import.

Starting from Python 2.7, the "import" statement is always absolute. So
the line:

import collections

will always find the first *top level* module or package "collections" in
the python search path. See below for an important proviso.

Inside your package, you can either use an explicit import like this:

import mypackage.collections as collections

or use a relative import like this:

from . import collections

Here is a concrete example. I create a package containing five files:

mypackage/
+-- __init__.py
+-- collections.py
+-- absolute_import.py
+-- explicit_import.py
+-- relative_import.py

with the following content:

# absolute_import.py
import collections

# explicit_import.py
import mypackage.collections as collections

# relative_import.py
from . import collections


The other two files (collections.py and __init__.py) can be blank. Now,
from *outside* the package, I can do this:


py> import mypackage.absolute_import
py> import mypackage.explicit_import
py> import mypackage.relative_import
py>
py> mypackage.absolute_import.collections
<module 'collections' from '/usr/local/lib/python3.3/collections/__init__.py'>
py> mypackage.explicit_import.collections
<module 'mypackage.collections' from './mypackage/collections.py'>
py> mypackage.relative_import.collections
<module 'mypackage.collections' from './mypackage/collections.py'>


Of course "from mypackage import absolute_import" etc. will also work.


However, beware: if you cd into the package directory, and then launch
Python, the current directory will contain a file "collections.py" which
will shadow the standard library collections.py. So don't do that.
 
F

Fabian von Romberg

Hi Steven,

thanks a lot for the explanation.

I will keep in mind not to use names for my modules that can shadow the standard library.

Regards,
Fabian
 
R

rocky

You can't. However, you can import explicitly from your package, or

implicitly by using a relative import.



Starting from Python 2.7, the "import" statement is always absolute. So

the line:



import collections



will always find the first *top level* module or package "collections" in

the python search path. See below for an important proviso.



Inside your package, you can either use an explicit import like this:



import mypackage.collections as collections



or use a relative import like this:



from . import collections



Here is a concrete example. I create a package containing five files:



mypackage/

+-- __init__.py

+-- collections.py

+-- absolute_import.py

+-- explicit_import.py

+-- relative_import.py



with the following content:



# absolute_import.py

import collections



# explicit_import.py

import mypackage.collections as collections



# relative_import.py

from . import collections





The other two files (collections.py and __init__.py) can be blank. Now,

from *outside* the package, I can do this:





py> import mypackage.absolute_import

py> import mypackage.explicit_import

py> import mypackage.relative_import

py>

py> mypackage.absolute_import.collections

<module 'collections' from '/usr/local/lib/python3.3/collections/__init__..py'>

py> mypackage.explicit_import.collections

<module 'mypackage.collections' from './mypackage/collections.py'>

py> mypackage.relative_import.collections

<module 'mypackage.collections' from './mypackage/collections.py'>





Of course "from mypackage import absolute_import" etc. will also work.





However, beware: if you cd into the package directory, and then launch

Python, the current directory will contain a file "collections.py" which

will shadow the standard library collections.py. So don't do that.

I find this kind of thing sad: it feels to me that programmers are working around somewhat arbitrary and changing restrictions. Rather than avoid names like "collections", why not try to address the underlying problem? There isn't an ambiguity here in my view: the fullname is mypackage.collections

It was for this reason I wrote import_relative http://code.google.com/p/pyimport-relative/.

It is far from perfect, but it pleases me to think that I one can adjust the language to do reasonable things rather than having it bend me into figuring out what's out there and limit the choice of names I use in submodules.
 
J

Jerry Hill

I find this kind of thing sad: it feels to me that programmers are working around somewhat arbitrary and changing restrictions. Rather than avoid names like "collections", why not try to address the underlying problem? There isn't an ambiguity here in my view: the fullname is mypackage.collections

You've said a couple of times now that the original author has a
package named "mypackage" with a module "collections" in it. As far
as I can tell, that's untrue. The original post claims to have a
package named "collections", which is colliding with the builtin
module of the same name.

As far as I can tell, all of your suggestions about using your
pyimport-relative tool aren't helpful unless the author re-names his
package from "collections" to "mypackage" and then moves all of their
code into a "collections" module inside "mypackage", right?
 
R

rocky

You've said a couple of times now that the original author has a

package named "mypackage" with a module "collections" in it. As far

as I can tell, that's untrue. The original post claims to have a

package named "collections", which is colliding with the builtin

module of the same name.



As far as I can tell, all of your suggestions about using your

pyimport-relative tool aren't helpful unless the author re-names his

package from "collections" to "mypackage" and then moves all of their

code into a "collections" module inside "mypackage", right?

Right. Perhaps then I misunderstand. Having a package called "collections" when there is something out there already called "collections" clearly ill advised.

But in that case, using sys.path to get around this is still a bad idea: the clash should be fixed. Sure, only in the case that this really can't be addressed would I use sys.path.
 
R

rocky

You've said a couple of times now that the original author has a

package named "mypackage" with a module "collections" in it. As far

as I can tell, that's untrue. The original post claims to have a

package named "collections", which is colliding with the builtin

module of the same name.



As far as I can tell, all of your suggestions about using your

pyimport-relative tool aren't helpful unless the author re-names his

package from "collections" to "mypackage" and then moves all of their

code into a "collections" module inside "mypackage", right?

Right. Perhaps then I misunderstand. Having a package called "collections" when there is something out there already called "collections" clearly ill advised.

But in that case, using sys.path to get around this is still a bad idea: the clash should be fixed. Sure, only in the case that this really can't be addressed would I use sys.path.
 
S

Steven D'Aprano

You've said a couple of times now that the original author has a package
named "mypackage" with a module "collections" in it. As far as I can
tell, that's untrue. The original post claims to have a package named
"collections", which is colliding with the builtin module of the same
name.

Ah, that would be my fault. I was the first one to mention "mypackage",
and I misread the OP's description.

Given that he has a *top-level* package "collections" which clashes with
the collections in the standard library, there's no simple way to bypass
his package and find the standard library collections module. When you
have two top-level modules/packages with the same name, whichever one
comes first in sys.path will shadow the second one.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top