How do I import Python files during execution?
I have created 3 file a.py,b.py and c.py in a path C:\Users\qksr\Desktop\Samples
The files contain the code as shown below:
a.py
from c import MyGlobals
def func2():
print MyGlobals.x
MyGlobals.x = 2
b.py
import a
from c import MyGlobals
def func1():
MyGlobals.x = 1
if __name__ == "__main__":
print MyGlobals.x
func1()
print MyGlobals.x
a.func2()
print MyGlobals.x
c.py
class MyGlobals(object):
x = 0
When I execute the code b.py the following error is thrown:
ImportError: No module named a
I believe my working directory is default and all the file a,b,c is just created by me in the samples folder.
How do I import python files in Python?
If you are working in the same directory, that is, b.py is in the same folder as a.py, I am unable to reproduce this problem (and do not know why this problem occurs), but it would be helpful if you post what os.getcwd() returns for b.py.
If that's not the case, add this on top of b.py
import sys
sys.path.append('PATH TO a.py')
OR if they are in the same path,
import sys
sys.path.append(os.basename(sys.argv[0])) # It should be there anyway but still..
There are many ways to import a python file:
Don't just hastily pick the first import strategy that works for you or else you'll have to rewrite the codebase later on when you find it doesn't meet your needs.
I start out explaining the the easiest console example #1, then move toward the most professional and robust program example #5
Example 1, Import a python module with python interpreter:
Put this in /home/el/foo/fox.py:
def what_does_the_fox_say():
print "vixens cry"
Get into the python interpreter:
el#apollo:/home/el/foo$ python
Python 2.7.3 (default, Sep 26 2013, 20:03:06)
>>> import fox
>>> fox.what_does_the_fox_say()
vixens cry
>>>
You invoked the python function what_does_the_fox_say() from within the file fox through the python interpreter.
Option 2, Use execfile in a script to execute the other python file in place:
Put this in /home/el/foo2/mylib.py:
def moobar():
print "hi"
Put this in /home/el/foo2/main.py:
execfile("/home/el/foo2/mylib.py")
moobar()
run the file:
el#apollo:/home/el/foo$ python main.py
hi
The function moobar was imported from mylib.py and made available in main.py
Option 3, Use from ... import ... functionality:
Put this in /home/el/foo3/chekov.py:
def question():
print "where are the nuclear wessels?"
Put this in /home/el/foo3/main.py:
from chekov import question
question()
Run it like this:
el#apollo:/home/el/foo3$ python main.py
where are the nuclear wessels?
If you defined other functions in chekov.py, they would not be available unless you import *
Option 4, Import riaa.py if it's in a different file location from where it is imported
Put this in /home/el/foo4/bittorrent/riaa.py:
def watchout_for_riaa_mpaa():
print "there are honeypot kesha songs on bittorrent that log IP " +
"addresses of seeders and leechers. Then comcast records strikes against " +
"that user and thus, the free internet was transmogified into " +
"a pay-per-view cable-tv enslavement device back in the 20th century."
Put this in /home/el/foo4/main.py:
import sys
import os
sys.path.append(os.path.abspath("/home/el/foo4/bittorrent"))
from riaa import *
watchout_for_riaa_mpaa()
Run it:
el#apollo:/home/el/foo4$ python main.py
there are honeypot kesha songs on bittorrent...
That imports everything in the foreign file from a different directory.
Option 5, Import files in python with the bare import command:
Make a new directory /home/el/foo5/
Make a new directory /home/el/foo5/herp
Make an empty file named __init__.py under herp:
el#apollo:/home/el/foo5/herp$ touch __init__.py
el#apollo:/home/el/foo5/herp$ ls
__init__.py
Make a new directory /home/el/foo5/herp/derp
Under derp, make another __init__.py file:
el#apollo:/home/el/foo5/herp/derp$ touch __init__.py
el#apollo:/home/el/foo5/herp/derp$ ls
__init__.py
Under /home/el/foo5/herp/derp make a new file called yolo.py Put this in there:
def skycake():
print "SkyCake evolves to stay just beyond the cognitive reach of " +
"the bulk of men. SKYCAKE!!"
The moment of truth, Make the new file /home/el/foo5/main.py, put this in there;
from herp.derp.yolo import skycake
skycake()
Run it:
el#apollo:/home/el/foo5$ python main.py
SkyCake evolves to stay just beyond the cognitive reach of the bulk
of men. SKYCAKE!!
The empty __init__.py file communicates to the python interpreter that the developer intends this directory to be an importable package.
If you want to see my post on how to include ALL .py files under a directory see here: https://stackoverflow.com/a/20753073/445131
Bonus protip, whether you are using Mac, Linux or Windows, you need to be using python's idle editor as described here. It will unlock your python world. http://www.youtube.com/watch?v=DkW5CSZ_VII
Tweaking PYTHONPATH is generally not a very good idea.
A better way is to make your current directory behave like a module, by adding a file named __init__.py, which can be empty.
Then the python interpretter allows you to import files from that directory.
Referring to: I would like to know how to import a file which is created in any path outside the default path ?
import sys
sys.path.append(directory_path) # a.py should be located here
By default, Python won't import modules from the current working directory. There's 2 (maybe more) solutions for this:
PYTHONPATH=. python my_file.py
which tells python to look for modules to import in ., or:
sys.path.append(os.path.dirname(__file__))
which modifies the import path on runtime, adding the directory of the 'current' file.
1st option: Add the path to your files to the default paths Pythons looks at.
import sys
sys.path.insert(0, 'C:/complete/path/to/my/directory')
2nd option: Add the path relative to your current root of your environment (current directory), using instead the following:
#Learn your current root
import os
os.getcwd()
#Change your current root (optional)
os.chdir('C:/new/root')
#Add the path from your current root '.' to your directory
import sys
sys.path.insert(0, './Path/from/current/root/to/my/directory')
Related
Here is my code:
from .Input import Choice27
import os
def New_File():
file_path = os.path.abspath(r"C:\Users\Me\Documents\Project\InputFolder\Test.txt")
Var1 = str(Choice27.Var[0])
Var2 = str(Choice27.Var[1])
with open(file_path, 'r') as file:
Output = file.read()
Replace = {'Find1':Var1,'Find2':Var2,}
for key, value in Replace.items():
Output = Output.replace(key, value)
It is giving me an error ImportError: attempted relative import with no known parent package.
My file structure for this test project is:
Project folder
Main.py
InputSubFolder
Input.py
Output.py
I know a beginner amount of python programming but I have never dealt with subfolders with my code. I use vscode for testing and auto-py-to-exe for compiling. I do not have any warnings before testing with vscode and receive no errors on compiling.
I have tried doing absolute pathing Ex. "from Input import Choice27", but I receive the same error.
I have also tried adding init.py to the subfolder even though I know it is not needed in my version of python.
On the Main.py, I can call import the modules with "import InputSubFolder.Input as IN, " which works just fine.
What kind of structuring or pathing do I need to do so that each file and subfolder can communicate if needed?
Inside your "Project folder/InputSubFolder", create a new file named __init__.py (two underscores before and after init keyword) and add following code:
from .Input import Choice27
Now inside Main.py, you can access Choice27 like this:
from InputSubFolder import Choice27
Adding __init__.py in a directory makes that directory a local Python package, containing all exportable classes, functions and variables which needs to be imported in some other Python file.
At the end, your project structure should be:
Project folder
Main.py
InputSubFolder
__init__.py
Input.py
Output.py
I have two files, say main.py and foo.py. When I import foo in main, I thought the lines in foo.py that not in a function automaticly run.
But when I add an executable to PATH in foo, and call main of foo that involves that executable which should be in PATH, it gives an error: geckodriver executable must be in PATH. If I add it to PATH right after the imports in main.py, it works correctly. Here are the sample codes:
main.py:
# some imports
from foo_file import foo
foo.main()
foo.py:
import os
FILENAME = os.path.dirname(os.path.abspath(__file__))
os.environ["PATH"] += os.pathsep + os.path.join(FILENAME, "assets")
def main():
# some work involves selenium
Why the first try doesn't work and gives the error? Thanks.
This is kind of a wild guess, but since you are importing foo as
from foo_file import foo
I assume that foo is in a sub-directory, i.e. something like
+- main.py
\- foo_file
\- foo.py
Thus, when you add os.path.abspath(__file__) to PATH, it will add the path of the subdirectory, not of the directory containing the main.py, which is probably the directory that contains the assets folder, since you said that it works fine if the PATH-adding code is directly in main.
You can easily check (a) that and when the code is executed, and (b) which path is retrieved, if you add an accordant print line in both the foo.py and main.py files, e.g.
print(__file__, os.path.dirname(os.path.abspath(__file__)))
I have a project a with several versions of main#.py so I organize them into a directory called run. I normally run project a from ./a by calling python run/main1.py. Because main1.py involves imports beyond the top level package, I need to specify sys.path.insert(0, "./") in main1.py.
Now I've created project b which imports main1.py from a. From b\main.py, how do I get main1.py to import a/utils.py specifically?
Requirements:
Project a is a project I worked on long ago so I would like to make limited changes to just its headers. I would like python run/main1.py to work like it currently does.
I may move the projects between different computers so main1.py needs to import utils.py relative to itself. (ie. not importing with absolute path)
I would like the solution to be scalable. b will need to import modules from several other projects structured like a. I feel that expanding the system's PATH variable may just mess things up. Is there a neater solution?
My projects' files are as follows:
a
run
main1.py
utils.py
b
main.py
utils.py
in a/run/main1.py:
import sys
sys.path.insert(0, "./")
from utils import hello # Anyway to specify this to be ../utils.py ?
hello()
in a/utils.py:
def hello():
print('hello from a')
in b/main.py:
import sys
sys.path.append("../")
from a.run import main1
import utils
utils.hello()
in b/utils.py:
def hello():
print('hello from b')
This is the current result. I would like the first line to print 'hello from a':
>>> python run/main1.py:
hello from a
>>> cd ../b
>>> python run/main.py:
hello from b (we want this to be "hello from a")
hello from b
I have code in one folder, and want to import code in an adjacent folder like this:
I am trying to import a python file in innerLayer2, into a file in innerLayer1
outerLayer:
innerLayer1
main.py
innerLayer2
functions.py
I created the following function to solve my problem, but there must be an easier way? This only works on windows aswell and I need it to work on both linux and windows.
# main.py
import sys
def goBackToFile(layerBackName, otherFile):
for path in sys.path:
titles = path.split('\\')
for index, name in enumerate(titles):
if name == layerBackName:
finalPath = '\\'.join(titles[:index+1])
return finalPath + '\\' + otherFile if otherFile != False else finalPath
sys.path.append(goBackToFile('outerLayer','innerLayer2'))
import functions
Is there an easier method which will work on all operating systems?
Edit: I know the easiest method is to put innerLayer2 inside of innerLayer1 but I cannot do that in this scenario. The files have to be adjacent.
Edit: Upon analysing answers this has received I have discovered the easiest method and have posted it as an answer below. Thankyou for your help.
Use . and .. to address within package structure as specified by PEP 328 et al.
Suppose you have the following structure:
proj/
script.py # supposed to be installed in bin folder
mypackage/ # supposed to be installed in sitelib folder
__init__.py # defines default exports if any
Inner1/
__init__.py # defines default exports from Inner1 if any
main.py
Inner2/
__init__.py # defines default exports from Inner2 if any
functions.py
Inner1.main should contain import string like this:
from ..Inner2 import functions
If you have to use the current directory design, I would suggest using a combination of sys and os to simplify your code:
import sys, os
sys.path.insert(1, os.path.join(sys.path[0], '..'))
from innerLayer2 import functions
Upon analysing answers I have received I have discovered the easiest solution: simply use this syntax to add the outerLayer directory to sys.path then import functions from innerLayer2:
# main.py
import sys
sys.path.append('..') # adds outerLayer to the sys.path (one layer up)
from innerLayer2 import functions
The easiest way is:
Move the innerLayer2 folder to inside the innerLayer1 folder
Add an empty file named __init__.py on the innerLayer2
On the main.py use the following:
import innerLayer2.functions as innerLayer2
# Eg of usage:
# innerLayer2.sum(1, 2)
I have a project with folder structure like this:
MainFolder/
__init__.py
Global.py
main.py
Drivers/
__init__.py
a.py
b.py
In Global.py I have declared like this:
#in Global.py file
global_value=''
Now when I tried the below script:
#in main.py
import Global
from Drivers import a
Global.global_value=5
a.print_value()
In a.py file
from MainFolder import Global
def print_value():
print Global.global_value
The output supposed to be like this:
5
But all I am getting is :
''
Anyone with this solution what happens when context changes??
In my opinion you should not do that. To have some form of common value, write the value to a file/db and then fetch the value from that file.
If that doesn't suite the needs, here's some resources I found, might help you out:
I've not tested this, but this one should work (fetched from Import a module from a relative path)
import os, sys, inspect
# realpath() will make your script run, even if you symlink it :)
cmd_folder = os.path.realpath(os.path.abspath(os.path.split(inspect.getfile( inspect.currentframe() ))[0]))
if cmd_folder not in sys.path:
sys.path.insert(0, cmd_folder)
# use this if you want to include modules from a subfolder
cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],"subfolder")))
if cmd_subfolder not in sys.path:
sys.path.insert(0, cmd_subfolder)
# Info:
# cmd_folder = os.path.dirname(os.path.abspath(__file__)) # DO NOT USE __file__ !!!
# __file__ fails if script is called in different ways on Windows
# __file__ fails if someone does os.chdir() before
# sys.argv[0] also fails because it doesn't not always contains the path
More:
Importing Python modules from different working directory
Python accessing modules from package that is distributed over different directories