I'm using portable-python and haven't been able to find a way of linking .py files to the portable-python interpreter (meaning I can't just double click my scripts to run them). I've been getting around this by dragging scripts into the path portable-python checks and then importing them.
ex:
import random_py_file
but is there a way to substitute the name of the file with its absolute/relative path?
ex:
import C:\file\script.py
This works on linux; however, I am not sure about windows. Essentially what you are doing is adding a path where python will look to find your script.
sys.path.append('C:\file')
import script
Look here to find how to make this permanent.
Related
This question already has answers here:
How can I import a module dynamically given the full path?
(35 answers)
Closed 1 year ago.
When I try to do using sys in following way, it gives error: name 'path' is not defined.
Here test.py is file in folder directory. Also folder directory has __init__.py in it.
import sys
sys.path.append('c/Users/Downloads/folder')
from test import *
print(path)
Content of test.py
path="sample"
I also tried writing from test import path but it did not work. So is there any other way than sys. I am not able to find why it's not working with it, since most answers recommend this.
EDIT:
Python is used a lot in industry so I am hopeful there must be some way for that (without using or using sys). I can have multiple files with same name in my system so help provided in answer and comments are not permanent fix.
This is an interesting problem so I spend a little time investigating. After some digging, it turns out the problem is there is already another script named "test.py" in one of the sys.path directories and Python is importing that script instead of the one you want.
When you import a module, Python looks for it in each of the search paths in the order they are listed in sys.path and imports the first match. Using sys.path.append('path/to/folder') fails because it adds a search path to the end of the list, and Python already finds a match for test.py in one of the directories listed before it. This is also the reason sys.path.insert(0,'path/to/folder') works - because it inserts the specified path at the front of the list so Python will find it first.
FIX
Change the name of the file 'test.py' to be something unique that won't match any other file names. This is the probably the best way.
You could use sys.path.insert(0,'path/to/folder') which places the specified path first in the list of search paths.
Another way is to go through each of the directories in the sys.path list and remove or rename the other "test.py" file(s). Not recommended
is there any other way than sys
If both the script you are running and the script you want to import are in the same folder, you don't need sys module.
If the files are in different folders and you absolutely won't use sys, then you can set PYTHONPATH in terminal before running the script. Note that you must run the python script from inside this same shell for it to work. Also, this will not work if the folder your script is in also contains a file with the same name as the one you want to import from another folder
Linux Bash:
export PYTHONPATH="path/to/folder/"
Windows Powershell:
set PYTHONPATH="path/to/folder/"
I'm currently trying to import one of my modules from a different folder.
Like this...
from Assets.resources.libs.pout import Printer, ForeColor, BackColor
This import method works completely fine in PyCharm, however, when i try to launch the file in cmd or IDLE, i get this error.
ModuleNotFoundError: No module named 'Assets'
This is my file structure from main.py to pout.py:
- Assets
- main.py
- resources
- libs
- pout.py
Any clue about how i could fix this ?
Any help is appreciated !
Edit: The original answer was based on the assumption that the script you're running is within the folder structure given, which a re-read tells me may not be true. The general solution is to do
sys.path.append('path_to_Assets')
but read below for more detail.
Original answer
The paths that modules can be loaded from will differ between the two methods of running the script.
If you add
import sys
print(sys.path)
to the top of your script before the imports you should be able to see the difference.
When you run it yourself the first entry will be the location of the script itself, followed by various system/environment paths. When you run it in PyCharm you will see the same first entry, followed by an entry for the top level of the project. This is how it finds the modules when run from PyCharm. This behaviour is controlled by the "Add content roots to PYTHONPATH" option in the run configuration.
Adding this path programmatically in a way that will work in all situations isn't trivial because, unlike PyCharm, your script doesn't have a concept of where the top level should be. BUT if you know you'll be running the script from the top level, i.e. your working directory will be the folder containing Assets and you're running something like python Assets/main.py then you can do
sys.path.append(os.path.abspath('.'))
and that will add the correct folder to the path.
Appending sys path didn't work for me on windows, hence here is the solution that worked for me:
Add an empty __init__.py file to each directory
i.e. in Assets, resources, libs.
Then try importing with only the base package names.
Worked for me!
In Python, I use some of my functions so often that I made a file where they are written, no matter the project I am working on. How do I tell Python to add this file to path every time my code is executed so that i can use my functions, just like adding a specific path to Pathtool in Matlab? I know in Python, I could do something like
sys.path.insert(1, 'D:/Python/FunctionDirectory') and then from file_with_functions import my_function but I would have to write this code to all of my projects before start coding to use my functions. I would like to always have the path to my functions added so that I can always use them like in Matlab without worrying about adding them in every single .py file.
you can use PYTHONPATH env var to specify folder where to look for modules
https://www.tutorialspoint.com/What-is-PYTHONPATH-environment-variable-in-Python
To provide complete steps for anyone with my problem for later times, I found my file with functions can be thought of as a module from which functions can be imported just like from file_with_functions import my_function.
But, I needed to add the folder with my module to python path. Messing with environment variables in Windows didn't work for me. Fortunately here, I read about a different solution:
I simply went to my site-packages folder (to find it, import sys then print(sys.path) and look for a name containing the string 'site-packages'). In this folder, I created a new text file and simply pasted the path with my module there:
like this, closed the text file and changed the extension from .txt to .pth (name of file did not matter as long as it was a .pth, Python found it).
While patching a program I wrote I noticed that I had no safe way to actually get the directory of 'libs', or even 'include' from within the Python installation itself. Every single time I tried to find any python used directory, I just assumed they would always be in the same place, and thus hard-coded them in. Now you might wonder why I am having trouble with this, I mean it's just a simple join call after a sys check, right?
import os, sys
python_base_directory = sys.exec_prefix
libs_directory = os.path.join(python_base_directory, 'libs')
This code works most of the time, but will fail when you are using a virtual environment, or in my case, using travis_ci.
I want to be able to get the path to the 'libs' directory without hard coding anything.
I was writing a program that accesses a .txt file at the start of the program with the open() function. It ran without any errors on the IDE and I was also able to read the text file when running from the IDE without any issues. Although when I ran from the Python Launcher it threw a "FileNotFoundError"
Here's my code:
directions_object = open('warcards_directions.txt','r')
Further to Dan D's comment.. try putting this on the line in front of your open() call:
from os.path import abspath
print(abspath('warcards_directions.txt'))
You'll see that python looks in different places depending on where you run it from .. because it looks for files relative to the current working directory, which changes depending on how you run python.
This is a common problem for new comers. See here How to import files in python using sys.path.append? for some solutions (note the underlying problem in that post is the same as this one.. the fact that they're trying to import a file, and here we're trying to open one is not too important).
Also I'll add that I often reference things relative to the script itself... like this:
from os.path import abspath, join, dirname
script_dir = dirname(__file__)
txt_path = abspath(join(script_dir, "..", "path", "to", "warcards_directions.txt"))
This works if your txt file and your python script stay in the same place relative to each other (but might be installed in different places).
E.g. above assumes your script lives in C:\Foo\scripts\script.py and your text file lives in C:\Foo\path\to\warcards_directions.txt. The method above will work fine where ever you run the script from and it'll work if you move or rename the C:\Foo dir (e.g. to C:\Program Files\Bar). But it'll break if you decide to move scripts.py down a directory into C:\Foo (at which point you change the way txt_path is initialized to fix).
When you said "python launcher", do you mean the command line?
python myScript.py
If you, you will need to cd into the directory where the file is at before you can execute the script. Otherwise, provide the full path to the txt file in your script.