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 thought I had understood the import system, however I'm struggling to understand an apparently trivial case: I have a very simple Python application with the following structure:
.
└── myapp
├── __init__.py
├── lib.py
└── myapp.py
The content of lib.py is a trivial function:
def funct():
print("hello from function in lib")
myapp.py is supposed to be the entrance point of the application:
import lib
def main():
lib.funct()
if __name__ == "__main__":
print("calling main")
main()
When I run the main script it works:
> python myapp/myapp.py
calling main
hello from function in lib
However, when I just import the package from IPython for instance, it fails:
In [2]: import myapp
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
<ipython-input-2-cabddf3cb27d> in <module>
----> 1 import myapp
~/test/myapp/__init__.py in <module>
----> 1 import myapp.myapp
~/test/myapp/myapp.py in <module>
----> 1 import lib
2
3
4 def main():
5 lib.funct()
ModuleNotFoundError: No module named 'lib'
Why is this happening? Eventually, I'd like that my application is executable with python -m myapp, but also importable.
By default the import searches for module on the paths present in sys.path and one of the path present there is of current directory so
when you executed the main script:
python myapp/myapp.py
The import in myapp.py file searched for lib module in its current directory i.e "myapp" and as lib.py is in same directory, it executed perfectly
But when you imported myapp as a package in IPython,
The import in myapp.py file searches from IPython's path, where Lib.py is not present hence the classic no module found.
There are few things you can do here
use relevant path in myapp.py like
from . import lib
Note: This will generate error if you executed myapp.py directly as a script so handle accordingly
update the sys.path by appending lib.py's path (Not Recommended)
sys.path.append("....../lib.py")
watch this for clear understanding.
Also just to point out, __name__=="__main__" is only true when you execute the file directly. so the code inside if in myapp.py will not work when you'll use it as a module in package.
I hope this was helpful :)
I've created a custom module called config which have the following structure:
config/
__init__.py
config.py
util.py
Each file is defined like:
config.py
CONTROL_VAR = "A"
util.py
from config import CONTROL_VAR
if CONTROL_VAR == "A":
VAR_ONE = "A1"
else:
VAR_ONE = "B1"
I've setup my workspace like the following:
workspace_folder
config/
my_script.py
In order tu run my script I invoke it directly by running:
python my_script.py
my_script.py has the following code:
from config.config import CONTROL_VAR
from config.util import VAR_ONE
if __name__ == "__main__":
print (CONTROL_VAR)
print (VAR_ONE)
I am able to run the code with python 2.7 but not with 3.8, at first I thought i was having a circular dependency issue but now it seems like I have something wrong with my import syntax.
Can I make this work for both python2 and python3?
When you perform from config import CONTROL_VAR inside config/util.py that module (util.py) doesn't know that it's located inside the config package and hence the resolution will start from my_script.py's directory. That means even the import happens inside a module which is located inside config, it attempts to resolve that import from the perspective outside of config.
In order to change that behavior, you can prefix config with a . which tells Python that the config.py module is expected to be in the same directory as the util.py module:
from .config import CONTROL_VAR
The from .foo import bar and from ..foo import bar syntax instructs Python so resolve imports relative to the importing module. A plain from foo import bar on the other hand resolves foo as a "global" module (i.e. not relative to anything).
Consider the following directory structure with the following contents:
my-project
├── main.py
├── lib
│ ├── __init__.py
│ ├── foo.py
│ └── bar.py
main.py
import sys
sys.path.append("./lib")
from foo import hello_world
if __name__ == "__main__":
hello_world()
foo.py
from lib.bar import name
def hello_world():
print(f"Hello {name}")
if __name__ == "__main__":
hello_world()
bar.py
name = "Grogu"
When I run main.py, I run into no errors and I get what I expect: Hello Grogu. However, when I run lib/foo.py, I get an error:
Traceback (most recent call last):
File "my-project/lib/foo.py", line 1, in <module>
from lib.bar import name
ModuleNotFoundError: No module named 'lib'
If I change lib.bar into bar, it works as expected, but I don't understand why VSCode doesn't seem to know what the lib folder is.
I'm using VSCode and I think there's something I'm doing wrong. My friend who uses pyCharm is able to run lib/foo.py just fine. It might have to be how VSCode and Pycharm interpret the source. Does anyone have any tips?
Basically I'm trying to import functions from a subdirectory and also preserve the ability to run individual files within the subdirectory, but I can't seem to find the proper way to do this in VScode.
When you execute a Python script, the specific directory where the script is located is added to the path, but not its parent's directory.
So, when you run python foo.py from inside lib the path will contain .../my-project/lib but not .../my-project, and therefore Python cannot find the module lib. However, it works with bar because the file does exist in .../my-project/lib.
To be able to run from both the root dir and lib, you can insert/append the parent directory (i.e. the root dir) to the path in the lib __init__.py:
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent))
Then, change main.py:
from lib.foo import hello_world
if __name__ == "__main__":
hello_world()
And foo.py:
from bar import name
def hello_world():
print(f"Hello {name}")
if __name__ == "__main__":
hello_world()
Just import bar directly:
foo and bar are both the modules that at the same level, there's no need to back to lib, then to search bar. We can directly run from bar import name.
More detailed information please refer to Python Docs - The import System
I have the following directory structure
foo/
__init__.py
settings.py
bar/
__init__.py
myfile.py
In myfile.py I have:
import settings
I get the following error: ImportError: No module named settings, why? How can I efectively import the settings file from myfile.py
From http://docs.python.org/2/tutorial/modules.html#intra-package-references :
from .. import settings
Hope it helps
Here is another method that seems more clear:
In foo.__init__.py:
__all__ = ['settings', ..(all other modules at 'foo' level you want to show)...]
In myfile.py:
# instead of "from .. import..."
from foo import settings
print settings.theThing