I have a file called tester.py, located on /project.
/project has a subdirectory called lib, with a file called BoxTime.py:
/project/tester.py
/project/lib/BoxTime.py
I want to import BoxTime from tester. I have tried this:
import lib.BoxTime
Which resulted:
Traceback (most recent call last):
File "./tester.py", line 3, in <module>
import lib.BoxTime
ImportError: No module named lib.BoxTime
Any ideas how to import BoxTime from the subdirectory?
EDIT
The __init__.py was the problem, but don't forget to refer to BoxTime as lib.BoxTime, or use:
import lib.BoxTime as BT
...
BT.bt_function()
Take a look at the Packages documentation (Section 6.4).
In short, you need to put a blank file named
__init__.py
in the lib directory.
Create a subdirectory named lib.
Create an empty file named lib\__init__.py.
In lib\BoxTime.py, write a function foo() like this:
def foo():
print "foo!"
In your client code in the directory above lib, write:
from lib import BoxTime
BoxTime.foo()
Run your client code. You will get:
foo!
Much later -- in linux, it would look like this:
% cd ~/tmp
% mkdir lib
% touch lib/__init__.py
% cat > lib/BoxTime.py << EOF
heredoc> def foo():
heredoc> print "foo!"
heredoc> EOF
% tree lib
lib
├── BoxTime.py
└── __init__.py
0 directories, 2 files
% python
Python 2.7.6 (default, Mar 22 2014, 22:59:56)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from lib import BoxTime
>>> BoxTime.foo()
foo!
You can try inserting it in sys.path:
sys.path.insert(0, './lib')
import BoxTime
I am writing this down because everyone seems to suggest that you have to create a lib directory.
You don't need to name your sub-directory lib. You can name it anything provided you put an __init__.py into it.
You can do that by entering the following command in a linux shell:
$ touch anything/__init__.py
So now you have this structure:
$ ls anything/
__init__.py
mylib.py
$ ls
main.py
Then you can import mylib into main.py like this:
from anything import mylib
mylib.myfun()
You can also import functions and classes like this:
from anything.mylib import MyClass
from anything.mylib import myfun
instance = MyClass()
result = myfun()
Any variable function or class you place inside __init__.py can also be accessed:
import anything
print(anything.myvar)
Or like this:
from anything import myvar
print(myvar)
Try import .lib.BoxTime. For more information read about relative import in PEP 328.
Does your lib directory contain a __init__.py file?
Python uses __init__.py to determine if a directory is a module.
Full example included
This basically covers all cases (make sure you have __init__.py in relative/path/to/your/lib/folder):
import sys, os
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/relative/path/to/your/lib/folder")
import someFileNameWhichIsInTheFolder
...
somefile.foo()
Example:
You have in your project folder:
/root/myproject/app.py
You have in another project folder:
/root/anotherproject/utils.py
/root/anotherproject/__init__.py
You want to use /root/anotherproject/utils.py and call foo function which is in it.
So you write in app.py:
import sys, os
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/../anotherproject")
import utils
utils.foo()
Create an empty file __init__.py in subdirectory /lib.
And add at the begin of main code
from __future__ import absolute_import
then
import lib.BoxTime as BT
...
BT.bt_function()
or better
from lib.BoxTime import bt_function
...
bt_function()
Just an addition to these answers.
If you want to import all files from all subdirectories, you can add this to the root of your file.
import sys, os
sys.path.extend([f'./{name}' for name in os.listdir(".") if os.path.isdir(name)])
And then you can simply import files from the subdirectories just as if these files are inside the current directory.
Working example
If I have the following directory with subdirectories in my project...
.
├── a.py
├── b.py
├── c.py
├── subdirectory_a
│ ├── d.py
│ └── e.py
├── subdirectory_b
│ └── f.py
├── subdirectory_c
│ └── g.py
└── subdirectory_d
└── h.py
I can put the following code inside my a.py file
import sys, os
sys.path.extend([f'./{name}' for name in os.listdir(".") if os.path.isdir(name)])
# And then you can import files just as if these files are inside the current directory
import b
import c
import d
import e
import f
import g
import h
In other words, this code will abstract from which directory the file is coming from.
For this folder hierarchy diagram example:
/project/tester.py
/project/lib/BoxTime.py
1- Create a blank py file __init__.py inside lib folder
2- In the caller py file tester.py add theses code lines
import os, sys
sys.path.insert(0,'lib')# insert the folder lib in system path
from BoxTime import Function_name # from the py file import the needed function
Easy explanation can be found in here.
Notice: This is refered to as creating/importing modules in/from different folder.
Personel experience: I tried to create module from jupyter notebook, it did not not work (maybe I done it improperly using .ipynb), I needed to do it manually outside the juypyter notebook, or using other IDE (e.g. pycharm).
create_card.py
init():
print('Hello world!')
app.py
import create_card
create_card.init()
if you want to import only required functions
from create_card import init
If you have nested directories (Ex: modules/aadhaar/create-card.py)
import modules.aadhaar.create_card as create_card or from modules.aadhaar.create_card import init
/project/tester.py
/project/lib/BoxTime.py
create blank file __init__.py down the line till you reach the file
/project/lib/somefolder/BoxTime.py
#lib -- needs has two items one __init__.py and a directory named somefolder
#somefolder has two items boxtime.py and __init__.py
try this:
from lib import BoxTime
I want to use relative import in Python 3.
My project:
main_folder
- __init__.py
- run.py
- tools.py
I want to have in run.py (MyClass declared in __init__.py):
from . import MyClass
And in run.py:
from .tools import my_func
An ImportError is raise.
Alternatively, with absolute import, debugging in PyCharm does not work and the library takes from installed packages, not my directory.
I know one way, but it is terrible:
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
How to use this import in my project?
When you use PyCharm, it automatically makes the current module main, so relative statements like from . import <module> will not work. read more here.
to fix your problem, put the __init__.py and tools.py files in a sub-directory
main_directory/
run.py
sub_directory/
__init__.py
tools.py
in your run.py file, write the following as your import statements
from sub_directory import tools
from sub_directory.__init__ import MyClass
Edit: as #9000 mentioned, you can write from sub_directory import MyClass and achieve the same thing.
I have my python source code and unittest code structure in the following hierarchy:
bin/
module1.py
module2.py
module3.py
test/
module1_test.py
The code in the modules are as follows:
module1.py
from module2 import testMethod1, testMethod2
def testMethodY():
...
...
...
module2.py
from module3 import testMethod4
module3.py
def testMethod4():
module1_test.py
import unittest
import sys, os
path = os.path.dirname(__file__)
path = os.path.join(path, 'bin')
sys.path.append("/bin")
from module1 import testMethodY
...(Some code for unit test)
when I run python module1_test.py
it fails with import error:
ImportError: cannot import name testMethod4
Not sure what is wrong. If I run the source code then all the imports are working fine. But with python unittest these relative imports are failing. Can anyone tell me what mistake i'm doing.
Create an __init__.py module in your tests folder and add the following to it:
import sys, os
path = os.path.dirname(__file__)
path = os.path.join(path, 'bin')
if path not in sys.path:
sys.path.append(path)
I think your path append statement is incorrect. You are appending /bin which would look for bin in the disk root.
sys.path.append("/usr/lib/bin")
The issue was because of another module with the same name coming from python libs. I renamed it and that solved the issue. Another approach that helped is setting the module to PYTHONPATH.
I have a python project that is like this :
py/
main.py
__init__.py
myapp/
__init__.py
my/
__init__.py
exam.py
sub/
__init__.py
index.py
and my file contains :
main.py :
from myapp.sub.index import *
cd = myc()
cd.doit()
exam.py -->
class myclass():
def hel(self):
print 'Hello world'
index.py -->
from myapp.my.exam import myclass
class myc():
def doit(self):
mycc = myclass()
mycc.hel()
I use fedora and when I use command:
python main.py
prints Hello world, but when I want to start main.py in my browser with apache and mod_python this error appears:
File "/var/www/html/py/main.py", line 1, in <module>
from myapp.sub.index import *
ImportError: No module named myapp.sub.index
Isn't relative import work in mod_python? what is the problem and what should I do?
I looks like the PYTHONPATH environment variable isn't correctly set when executing the module under mod_python.
A workaround to the problem, using the directory structure described in the question, would be to add this to main.py file:
import sys, os
sys.path.insert(0, os.path.dirname(__file__))
I created my own Django application with directory structure
/appname
__init__.py
models.py
/submodule1
__init__.py
a.py
Inside a.py I have the following import
from ..models import Something
This works okay if I have /appname inside my /djangoproject folder, but when I install the app to Python's site-packages (via setup.py which I created), all hell breaks loose and a.py can no longer import Something, with the following error:
ImportError: cannot import name Something
Here is the setup.py:
from distutils.core import setup
setup(name='appname',
version='0.1',
packages=['appname', 'appname.contrib'],
)
It turns out that it was a circular import error. models.py was importing a.py and a.py was importing models.py.
Breaking this circle solved the import issues, but now it is time to figure out how to do lazy evaluation in Python :-)
Put empty file named: __init__.py inside /submodule1 so Python can parse it as module. It should help. The same in /appname - there should be also __init__.py file