I am using Python 2.7. I have the following directory structure:
alogos
- resources
- __init__.py
- test.py
- lib
- __init__.py
- utils.py
- common
- config
- config.json
My utils.py is the following:
def read_json_data(filename):
with open(filename) as data:
json_data=json.load(data)
return json_data
My test.py has the following:
from lib.utils import read_json_data
running_data = read_json_data('common/config/config.json')
print running_data
when I try to run python test.py from the resources directory, I get the following error:
ImportError: No module named lib.utils
What is the correct way to access files and modules
Your lib.utils module is not present in the current directory (and apparently not anywhere else import checks), and so the import fails.
The Python doc details the module search path:
When a module named spam is imported, the interpreter first searches
for a built-in module with that name. If not found, it then searches
for a file named spam.py in a list of directories given by the
variable sys.path. sys.path is initialized from these locations:
* the directory containing the input script (or the current directory).
* PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).
* the installation-dependent default.
After initialization, Python programs can modify sys.path. The
directory containing the script being run is placed at the beginning
of the search path, ahead of the standard library path. This means
that scripts in that directory will be loaded instead of modules of
the same name in the library directory. This is an error unless the
replacement is intended. See section Standard Modules for more
information.
While this is certainly not the only way, what I would do would be to have your lib.utils module as a separate module, stored in a local Pypi server (Artifactory is one example, but there are others, such as devpi) where you can install it just like any other module, just from a different index URL from the regular Pypi. That way, any of your scripts can use it just like any other module, and it obviates the need to play assorted path-related games that can add unnecessary complexity.
Related
This is a python newbie question:
I have the following directory structure:
test
-- test_file.py
a
-- b
-- module.py
where test, a and b are folders. Both test and a are on the same level.
module.py has a class called shape, and I want to instantiate an instance of it in test_file.py. How can I do so?
I have tried:
from a.b import module
but I got:
ImportError: No module named a.b
What you want is a relative import like:
from ..a.b import module
The problem with this is that it doesn't work if you are calling test_file.py as your main module. As stated here:
Note that both explicit and implicit relative imports are based on the name of the current module. Since the name of the main module is always "main", modules intended for use as the main module of a Python application should always use absolute imports.
So, if you want to call test_file.py as your main module, then you should consider changing the structure of your modules and using an absolute import, else just use the relative import from above.
The directory a needs to be a package. Add an __init__.py file to make it a package, which is a step up from being a simple directory.
The directory b also needs to be a subpackage of a. Add an __init__.py file.
The directory test should probably also be a package. Hard to say if this is necessary or not. It's usually a good idea for every directory of Python modules to be a formal package.
In order to import, the package needs to be on sys.path; this is built from the PYTHONPATH environment variable. By default the installed site-packages and the current working directory are (effectively) the only two places where a package can be found.
That means that a must either be installed, or, your current working directory must also be a package one level above a.
OR, you need to set your PYTHONPATH environment variable to include a.
http://docs.python.org/tutorial/modules.html#the-module-search-path
http://docs.python.org/using/cmdline.html#envvar-PYTHONPATH
Also, http://docs.python.org/library/site.html for complete information on how sys.path is built.
The first thing to do would be to quickly browse the official docs on this.
To make a directory a package, you'll have to add a __init__.py file. This means that you'll have such a file in the a and b directories. Then you can directly do an
import a.b.module
But you'll have to refer to it as a.b.module which is tedious so you can use the as form of the import like so
import a.b.module as mod #shorter name
and refer to it as mod.
Then you can instantiate things inside mod using the regular conventions like mod.shape().
There are a few other subtleties. Please go through the docs for details.
I ran my project and received the following error:
File "/home/nguyentv/schoollink/web/views/apis.py", line 10, in <module>
from util.redis.redis_client import Redis
ImportError: No module named util.redis.redis_client
How do I properly import this library?
The Module Search Path
When a module named spam is imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path. sys.path is initialized from these locations:
the directory containing the input script (or the current directory). PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).
the installation-dependent default.
After initialization, Python programs can modify sys.path. The directory containing the script being run is placed at the beginning of the search path, ahead of the standard library path. This means that scripts in that directory will be loaded instead of modules of the same name in the library directory. This is an error unless the replacement is intended. See section Standard Modules for more information.
Basically, the interpreter is going to perform a lookup in your current working directory, then it will search through the system defined library directories.
The issue you are facing could be that your code is looking for a module that does not exist, you are calling the script from an incorrect directory, or the sys.path is setup incorrectly.
I could help more if you showed how you instantiated the interpreter, pwd output, and tree output.
You are trying to import Redis from a package named util. Unless this package is part of your application, it does not exist.
According to python-redis' documentation, here is how to import it:
import redis
# then use redis.Redis(...)
or, equivalently:
from redis import Redis
# then use Redis(...)
I have created a custom libraries which have following folder structure:
DS
-lib
-init__.py
-db.py
-dispatch.py
-links.py
Now I want to consume files under lib in the following folder structure:
apps
- framework
-- test.py
When I do from DS.lib.dispatch import * in test.py it gives error:
from lib.db import Links ImportError: No module named 'lib'
Update
dispatch.py
from lib.db import Links
from lib.links import Link
import numpy as np
from urllib.parse import urlparse
class Dispatch:
"""
This will pull an individual unprocessed link and pass to dispatcher
"""
_idle_link = None
...
There is more to this topic than I can explain here, but in the simple case of python packages and modules on the file system, it works roughly as follows. Given the following files:
Modules
A module is a simple .py file. These files can be located anywhere on the file system, and do not have to be in a package. A module usually contains class and function declarations. Any code outside of a function/class definition is executed when the module is run/imported.
/someplace/foo.py
def func():
print "I am foo.func"
print "I run at module import"
Packages
A package is a directory containing an __init__.py. A package can also be located anywhere in the filesystem. The __init__.py module is executed when the package is imported and the contents of this module becomes the contents of the package.
/anotherplace/bar/__init__.py
def func():
print "I am bar.func"
print "I run at package import"
A package contains modules or other child packages. Child modules are not automatically imported.
/anotherplace/bar/child.py
def func():
print "I am bar.baz.func"
print "I run at module import"
Imports
Both modules and packages can be imported from other modules.
When python sees an import statement, it searches certain directories for the code. These directories are the module search path. The search path is made up of:
the current working directory
the PYTHONPATH environment variable
system defaults
You can inspect the current module search path at runtime:
import sys
print sys.path
You will note that in the examples above, I have put foo in /someplace/ and bar in /anotherplace/.
If I were to run the python interpreter in /someplace/ then import foo would succeed (because it's found at the current working directory). However import bar would fail, because /anotherplace/ is not on the search path.
For both imports to work, both source folders must be on the search path. Note that the correct source folder for a package is the directory above the one with __init__.py. In this case, it should be:
/someplace/
/anotherplace/
What exactly is the use of __init__.py? Yes, I know this file makes a directory into an importable package. However, consider the following example:
project/
foo/
__init__.py
a.py
bar/
b.py
If I want to import a into b, I have to add following statement:
sys.path.append('/path_to_foo')
import foo.a
This will run successfully with or without __init__.py. However, if there is not an sys.path.append statement, a "no module" error will occur, with or without __init__.py. This makes it seem lik eonly the system path matters, and that __init__.py does not have any effect.
Why would this import work without __init__.py?
__init__.py has nothing to do with whether Python can find your package. You've run your code in such a way that your package isn't on the search path by default, but if you had run it differently or configured your PYTHONPATH differently, the sys.path.append would have been unnecessary.
__init__.py used to be necessary to create a package, and in most cases, you should still provide it. Since Python 3.3, though, a folder without an __init__.py can be considered part of an implicit namespace package, a feature for splitting a package across multiple directories.
During import processing, the import machinery will continue to
iterate over each directory in the parent path as it does in Python
3.2. While looking for a module or package named "foo", for each directory in the parent path:
If <directory>/foo/__init__.py is found, a regular package is imported and returned.
If not, but <directory>/foo.{py,pyc,so,pyd} is found, a module is imported and returned. The exact list of extension varies by platform
and whether the -O flag is specified. The list here is
representative.
If not, but <directory>/foo is found and is a directory, it is recorded and the scan continues with the next directory in the parent
path.
Otherwise the scan continues with the next directory in the parent path.
If the scan completes without returning a module or package, and at
least one directory was recorded, then a namespace package is created.
If you really want to avoid __init__.py for some reason, you don't sys.path. Rather, create a module object and set its __path__ to a list of directories.
if I want to import a into b, I have to add following statement:
No! You'd just say: import foo.a. All this is provided you run the entire package at once using python -m main.module where main.module is the entry point to your entire application. It imports all other modules, and the modules that import more modules will try to look for them from the root of this project. For instance, foo.bar.c will import as foo.bar.b
Then it seems that only the system path matters and init.py does not have any effect.
You need to modify sys.path only when you are importing modules from locations that are not in your project, or the places where python looks for libraries. __init__.py not only makes a folder look like a package, it also does a few more things like "export" objects to outside world (__all__)
When you import something it has to either:
Retrieve an already loaded module or
Load the module that was imported
When you do import foo and python finds a folder called foo in a folder on your sys.path then it will look in that folder for an __init__.py to be considered the top level module.
(Note that if the package is not on your sys.path then you would need to append it's location to be able to import it.)
If that is not present it will look for a __init__.pyc version possibly in the __pycache__ folder, if that is also missing then that folder foo is not considered a loadable python package. If no other options for foo are found then an ImportError is raised.
If you try deleting the __init__.pyc file as well you will see that the the initializer script for a package is indeed necessary.
This questions is detailing a behavior that I can't explain to myself.
src/package/__init__.py is empty but present.
src/package/subpackage/__init__.py:
pink = 'It works'
src/package/test/test.py:
import package.subpackage as subpackage
# I also tried `import package.subpackage as subpackage
print subpackage.pink
Calling from src: python package/test/test.py just fails with ImportError: No module named subpackage. Please note that import package doesn't work either.
NB: (Running an interpreter from src and typing the import statement works perfectly well.
Should I understand that I'm not suppose to call subfile of a package? In my project it's a test file so it sounds logical for me have it here.
Why the current working directory is not in the import path?
Many thanks for those who reads and those who answers.
Because you package is not in $PYTHONPATH. If you what to call test.py, you can move your test.py file to src/ directory, or add src to $PYTHONPATH
PYTHONPATH="/path/to/src:$PYTHONPATH"
export PYTHONPATH
From Documentation
When a module named spam is imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path
>>> import sys
>>> sys.path
The output is like this
['.', '/usr/bin', ...
This means that the current directory is in sys.path as well. If you want to import a module, please make sure that the module path is in sys.path, by adding your package directory to the environment variable PYTHONPATH, or changing your current directory or script directory to the package directory.
On python package/test/test.py fails, it's also ran from src:
when you starts a intepreter from src, '' is in sys.path, so path of src could be found;
when you run python package/test/test.py from src, '' is missing from sys.path, although os.path.abspath('.') shows current dir is "<xxx>\\src", "<xxx>\\src" is not in sys.path, while "<xxx>\\src\\package\\test" is in sys.path. That's saying, python adds path of the file to sys.path, not the path where you run the script.
see what the docs says:
As initialized upon program startup, the first item of this list, path[0], is the directory containing the script that was used to invoke the Python interpreter. If the script directory is not available (e.g. if the interpreter is invoked interactively or if the script is read from standard input), path[0] is the empty string, which directs Python to search modules in the current directory first. Notice that the script directory is inserted before the entries inserted as a result of PYTHONPATH.