I wrote a python package that includes many modules. The modules import each other within the package.
Now after it is complete I wish to move my package inside a different package as a subdirectory. But I can't do it because now all the imports get errors because they can't find the modules on their new path.
For example -
In module my_package.a I have:
x = 5
In module my_package.b:
from my_package.a import x
print x
Before I did: from my_package import b, and now I wish to do from tools.my_package import b, and get the same result.
What is the right way to change a package logic path without having to add the new path to sys.path?
I would use relative imports internally:
from .a import x
If your module is self-contained, you can relocate it without issues if it uses relative imports.
Related
My folder structure is
fold1/fold2/a.py
fold1/fold3/b.py
fold1/fold3/c.py
a.py is doing
from fold1.fold3 import c
c.py is doing
import b
When I run a.py, I am getting error "No module named b"
I have __init__.py in all folders, but still why I am getting that error.
I know that lastly python checks for packages in current directory, so here current directory is "fold2" and I am not finding "b.py" in that fold2? but both "c.py" and "b.py" are in same directories right but still why I am getting that error?
Edit: The code is generated by pyxb python module, so I cannot change import statements.
import b is an absolute import: b has to be found in a package listed in sys.path.
In order to import b relative to the package containing c, use the relative import
from . import b
. refers to the package containing c (fold3). .. would refer to the package containing that package (fold1). You could also write
from ..fold3 import b
.. refers to fold1, so ..fold3 refers to the module fold3 in the package fold1.
When using relative imports, it doesn't matter where fold1 exists: it could be in sys.path, it could be a submodule of some other package. As long as the internal structure of fold1 remains the same, the relative imports will continue to work the same.
All the paths are relative to where you start the interpreter from!
c.py is looking for b in the parent of fold1
try using a form like from fold1.fold3 import b instead
I've tried to create a new module in Python. It's git link : https://github.com/Sanmitha-Sadhishkumar/strman
After uploading and installing that using pip, I found that I could access that module as
import strman.strman as s
s.func_name
What are the changes to be made to access that as
import strman
strman.func_name
In your __init__.py file, you want to use a relative import.
from .strman import *
You have a strman package (the outer directory) and within it a strman module (the strman.py file). That's a perfectly common pattern. But without the relative import your __init__.py wasn't importing from deep enough in the hierarchy.
More generally, whenever you import from a sibling module within a project, you almost always should use a relative import, because it's explicit and avoids various complications, such as the example in your case.
You have to move the files into the main directory. Your directory will look like this
\myProject
- init.py
- strman.py
- main.py # <-- this would be the file your programming is
Read more about modules in the docs
It seems that I am still missing some basics of python. I was trying to understand submodules importing, which I feel I have not understood yet. But I have also stumbled upon something new.
I am having following two packages in two different PyDev projects:
package1
|
+--mod1.py
|
+--mod2.py
package2
|
+--__init__.py
|
+--modx.py
|
+--mody.py
In mod1, I can do import mod2. But in __init__ and modx, I cannot do import mody (Eclipse says "unresolved imports"). In __init__, I can do import .mody or from .mody import vary. In modx, I cannot do import .mody. (In fact I never saw use of . in import statement as prefix to the module. Earlier I only came across import mod and from mod import var, but never saw import .mod and from .mod import var.) Why this might be happening? I must be unaware some context which is causing this behaviour. But then I dont know what is it?
PS: I am using Python 3.4
There is a subtle different between how Python is treating both of those packages.
package1 is treated as a namespace package in that it does not contain an __init__.py file.
package2 is treated as a regular package in that it does contain an __init__.py file.
So I'll give a quick breakdown of why each step is happening:
In mod1, I can do import mod2.
This is happening due to how namespace packages are handled using absolute imports. You're most likely executing python mod1.py from the directory in which the file is stored, right (in my attempt to re-create your folder structure and test it myself locally, I did the same)? So package1 becomes your current working directory with your mod2 file being at the root of that directory.
With namespace packages, Python will default look to sys.path in an attempt to find the imports you have requested. Since your current working directory is automatically added to and included in sys.path, Python can successfully find your import mod2 request without any difficulty.
Thanks to ShadowRanger for correcting my initial response to this where I had misunderstood exactly how Python is including the current working directory in its search.
In init, I can do import .mody or from .mody import vary.
This is because Python is treating this as a regular package. The name of your regular package in this case is package2. When you use the . notation, you are asking Python to start searching for the import from the current package (which in this case is your parent package2). So you have to use import .mody to find the mody package within the current package.
If you used .. then it would import from the parent of the current package and so on.
The dot notation is useful as you are explicitly declaring that you wish to search from the current package only - so if there was another package2 package on your PYTHONPATH, Python would know which one to choose.
But in init and modx, I cannot do import mody (Eclipse says "unresolved imports").
With __init__.py this is because you have not used the dot notation and have not told Python that you wish to search for these modules in the current package. So it's looking to the Python standard library and to your PYTHONPATH for these packages and not finding them (hence your error in Eclipse). By using the dot notation, you are stating that you wish to include the current package in the search and, thus, Python will then be able to locate those files.
Using the dot notation like this, to import via from . import mody, is to use a relative import.
With modx you also have to use a relative import (see next section).
In modx, I cannot do import .mody. Why this might be happening?
This is because you're not using a relative / absolute import. You'll be using a relative import in this case. A relative import is the from . import mody syntax you've seen already. Using a relative or absolute import behaviour is default in Python.
It is now the default behaviour as, with the old Python import behaviour, suppose Python's own standard library had a package called mody. When you'd use import mody it would previously have imported mody from your package and not the standard library. This wasn't always desirable. What if you specifically wanted the standard library version?
So now your imports must be made using from . import mody or from .mody import vary syntax so as the import is very clear. If you use import and not the from... syntax, Python will assume it's a standard library or PYTHONPATH import.
By the way, sources for a lot of the above information came from the following sites:
https://docs.python.org/3/reference/import.html
https://docs.python.org/2.5/whatsnew/pep-328.html
Python modules are optional "additions" to Python that can be imported using the import command like so:
import package1
package1.mod1 # Can be accessed using this
To import individual parts of the package, use from like so:
from package1 import mod1
mod1 # Can be accessed using this
If you want to import every part of a module and use it without package., use:
from package1 i
I get an ImportError when I am importing from a sub-module in the way I thought One Was Supposed To Do It.
I have the following package:
pkg/
__init__.py
cow.py
pizza.py
pkg.py
components/
components.py
otherstuff.py
__init__.py
cow.py:
print "Hello"
from components import foodle
components.py:
foodle=5
and the __init__'s are empty.
I am having trouble putting things in the right place or organizing them properly. When, from the pkg directory, I try
from pkg import foodle
I get "ImportError: cannot import name foodle"
What is the right way to arrange files and import from submodules? I have read How to import python file from git submodule ; I have tried messing with sys.path in components/__init__.py and in cow.py, to no avail.
This package is shared on git, so it needs to be portable. components is actually a git sub-module.
Putting from components import * in the __init__py in components/ seems to work, but I thought usually that file stays empty.
The elements I was missing are (these are my interpretation, may still be incorrect):
If it's a package (with __init__.py), use it from outside the pkg folder, not from inside. ie, using a package both ways (calling from outside and using modules from within) might be hard to set up, so don't. This is the main insight that solves my problem.
the dot notation for getting submodules and subpackages works both for files and for folders within pkg. Thus, from some other folder, but with pkg in my path, I can call any of the following:
import pkg
from pkg.cow import foodle
from pkg.components import foodle
from pkg.components.components import foodle
This question already has an answer here:
A Python module and package loading confusion
(1 answer)
Closed 9 years ago.
I am porting some matlab code to python. I need to work with packages and modules in this case. The relevant package directory structure looks like this:
toppackage
__init__.py
subpackage
__init__.py
module.py
...
In the script I use the package, I can work like this:
from toppackage.subpackage.module import SomeClass
s = SomeClass()
But I would prefer working like this:
import toppackage %somewhere at the beginning of file
s = toppackage.subpackage.module.SomeClass()
I see this is done in numpy. But I could not find it in documentation. How can I do that?
Thanks in advance.
You need to import contained packages in the __init__.py files.
You can import the packages inside the toppackage/__init__.py for example:
import toppackage.subpackage.module
or you can import just each directly contained package, so in toppackage/__init__.py:
from . import subpackage
and in toppackage/subpackage/__init__.py:
from . import module
Just importing the top-level package does not automatically make the contained packages available. You need to explicitly import the full path once, somewhere, before that works.
The numpy package imports the nested packages in the top-level __init__.py.
How this stuff works depends critically on what is in __init__.py. Whatever gets imported in that script becomes part of the package namespace.
For example, if your toppackage/__init__.py is empty, to gain access to subpackage, you'd need to do:
import toppackage
try:
p = toppackage.subpackage
except AttributeError:
print "you would see this"
import toppackage.subpackage
p = toppackage.subpackage #no error now
however, if toppackage/__init__.py included the line:
#toppackage/__init__.py
import subpackage
Then the above script would raise no Exceptions.
As noted in the comments, you can also use relative imports since you are in a package:
from . import subpackage
This avoids "namespace" conflicts -- e.g. if you have a subpackage named os it will get your subpackage rather than the python-level package.