I have a folder with the following layout:
root/
package0/
__init__.py
main.py
package1/
__init__.py
main.py
Inside the package1/main.pyI have import package0.
When I open a terminal on root folder and run python package1/main.py it works fine. But this is very strange since the cwd was not supposed to be included in path, only the folder in which the script is in, package1 in this case.
When I print the sys.path I can see that the root folder is there.
When I run the same code on my other computer I get a import error as expected.
I cannot understand why I am seeing this behavior.
I have already checked .bashrc and there is no code adding the cwd to the python path.
What might be different on the two computers, I am transferring the root folder from one computer to another through git.
Essentially, whenever you start a particular script, the 'working directory' is the directory from which you started the script. When you run your script from the root folder using command line, the script will look for any files you mention with the root folder as the 'root' of any paths.
Hope that addressed some of your questions. If you're interested in working with changing the starting directory, you can read more about it here.
Edit: Continuation on how to solve changing the working directory for any particular file, this should grab your current running file's directory, change the path to it, and change the directory one higher.
import os
dir_path = os.path.dirname(os.path.realpath(__file__))
os.chdir(dir_path)
os.chdir("..")
I found a solution. I have no idea of why this solved the problem.
I had two folders added to my pythonpath on .bashrc, some TensorFlow stuff, nothing related to this task.
When I commented the line that added these folders, my cwd stopped to be added to the pythonpath. I took a look into those folders but I could not figure out what was causing this.
I am still curious anyway.
Related
In Pycharm, if you right click in a folder inside your project, you can mark it as sources root, so then you can import modules from this folder and subfolders.
However doing it this way will only make your program runnable inside Pycharm, if I try to execute from outside Pycharm (eg from the console) it will complain that certain modules are not found, which is the problem that I'm facing.
If I mark a certain folder as sources root my program runs fine, but I need to understand what does it do so I can configure the program to find this modules even if not using Pycharm.
I want to know what does this option exactly do, and how can I get the same behaviour without using it.
It is just adding a __init__.py file in the root folder?
Is it doing something like:
import sys
sys.path.insert(0, my_folder)
First __init__.py marks a directory as a regular package directory(this is pre 3.3, in 3.3+ its not required anymore). With this, python will look for submodules inside that directory for imports.
"Mark directory as sources root" sets the PATH(or PYTHONPATH) for the environment. In shell, it will be like,
export PYTHONPATH="${PYTHONPATH}:/your/source/root"
PYTHONPATH holds the default search path for module files.
This will enable the interpreter to search for the modules in the appended path. The default value is installation dependent(normally it contains path to Python binaries).
You can also manipulate this search path using sys.path from inside a python file.
I have already tried appending the path to sys.path, but that doesn't solve the problem either. The import works fine with my Python36 interpreter.
My directory structure is:
project (dir)
:main.py
:=> Algorithms (sub-dir)
:==> AlgoOne.py
My code in the entry file which is one level above the Algorithms dir is:
#main.py
from Algorithms.AlgoOne.py import ClassOne
Any ideas why this could happen, or how I instruct jython to read the directory as a module like Python36?
Thanks
Saying I create a.py under path/to/somewhere/. And later in the IDE(pycharm), I refactor it to path/to/another_place/.
But when I run a.py later, os.getcwd() show its working directory is still in path/to/somewhere. ( os.listdir('.') also show it is in original place.)
The following picture is what I meet , makeimg.py is originally in learn_function
I am new to python and I don't understand how a file/modoule locate itself.
Am I do something wrong? or it is a bug?
os.getcwd() returns the current working directory, it may/may not be the directory in which the your script exists, its the directory from which the script was run. Most probably in your PyCharm Run/Debug configuration you have set the Working directory to path/to/somewhere .
From run/debug configuration doc page for pycharm -
Working directory - Specify a directory to be used by the running task.
When a default run/debug configuration is created by the keyboard shortcut Ctrl+Shift+F10 , or by choosing Run on the context menu of a script, the working directory is the one that contains the executable script. This directory may differ from the project directory.
Ideally your code should not depend on the current working directory , since you can run a python file from anywhere using absolute path to the python file.
Instead if you want the path in which the script resides, use __file__ to get that path in the script.
Example -
print(__file__)
This should print the script's path (as given in sys.argv[0]).
I recently figured out how to import modules for unittesting in python. As a solution to this, I use:
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from Dev.test import someclass
This works fine while running in PyCharm and I get the expected output. However, when I run from terminal I run into an error:
ImportError: No module named Dev.test
I have the init files where they are supposed to be but I'm lost as to why this is working in PyCharm but not from the terminal. I have not changed my path or anything in PyCharm as this code is supposed to be able to run with minimal modifications on other machines. Any idea as to why this is happening and what I might be able to do to fix it?
My folder structure is as follows
-Current
-Dev
-__init__.py
-test
- __init__.py
-someclass.py
-Tests
-__init__.py
-someunittest.py
I have tried running someunittest from the main folder as well as with a complete path but it only works in PyCharm
sys.path.append(os.getcwd()[:os.getcwd().index('Dev')])
I added this to my imports and it seems to have solved the problem. However, this doesn't seem like it would be the right way to do it; it will do for now.
When running a script from within PyCharm, it runs it in an environment with PYTHONPATH set to the list of all the folders that are marked "Sources Root" (with a blue folder icon) in the project explorer.
Outside of PyCharm, PYTHONPATH is not normally set. The first entry in sys.path refers to the current working directory where the script was run from. As long as you run your script with your terminal's working directory as the folder containing Dev, it should be able to find the Dev.test module, regardless of the extra entry added to sys.path.
Once you get the working directory correct, you should be able to remove the sys.path hack.
What #codewarrior has said about the PyCharm setting its own PYTHONPATH is correct. But sys.path didn't have my current working directory. So to get around this problem, I updated my PYTHONPATH (or you can edit sys.path).
Setting PYTHONPATH
export PYTHONPATH=$PYTHONPATH:`pwd` (OR your project root directory)
Updating sys.path
import sys
sys.path.insert(0,'<project directory>') OR
sys.path.append('<project directory>')
You can use insert/append based on the order in which you want your project to be searched.
HTH.
Pycharm uses a virtual environment. When you try run your program in your terminal this enviroment isn't active.
You need to build or upload your enviroment Pycharm with your libraries.
cd to the directory project and write in terminal:
source venv/bin/activate
I too have had this issue - and the PYTHONPATH setting set by PyCharm did seem to be the issue.
My alternative (as I was nearly finished writing the code) was to generate a setup.py - and install the classes/structure in my local virtual Python environment.
I would recommend trying out $ pip install . in your source directory. This will install your own packages for your project.
To add to similar answers here, PyCharm is doing some extra config for you before running your script. If adding your sources root to PYTHONPATH doesn't work then examine your run configuration in PyCharm for the script in question, there will likely be some more behind the scenes magic at play.
I had similar problem. I think the problem is that Pycharm modifies PYTHONPATH so before running your script:
cd to the file where python file resides
run export PYTHONPATH=.
run the script
You can also create "main" python file where you set the python path and then call the other modules
Up to this point I have organized my projects in such a way that everything I'm working on is in the same folder, so to play around/debug I have just launched Python from that folder like this:
C:\Users\Username\Dropbox\Projects\MyShinyProject>Python
>>>
However, I want to start organizing things better. I have created some "Utilities" classes that I expect I'll use over and over again. So they should be in their own folder.
So now, say I have a Projects folder (in Windows) with lots of subfolders of things I have been working on:
Projects
Sandbox
Sandbox1
Sandbox2
MyUtilities
__init__.py
Utility1.py
MyShinyProject
__init__.py
ImportantClass.py
I would like to be able to go into the command prompt and use classes/functions from both the MyUtilities folder and from the MyShinyProject folder. However, if I launch Python from inside MyShinyProject, I don't have access to MyUtilities (or vice versa). I've tried doing a relative import like this:
>>>import ..MyUtilities.Utility1
But that doesn't work:
import ..MyUtilities.Utility1
^
SyntaxError
If it matters: I don't use an IDE. I just use Notepad++ and the command prompt. Also, I added the __init__.py files to the folders because I read somewhere you're supposed to do that when you make modules, but I don't understand how to get all of this working correctly, or if I'm even close to doing it right.
I also tried adding my Projects folder to the PATH variable in the Windows environment table, but that doesn't seem to work. Even after adding it importing doesn't work, and when I do this:
import sys
for x in sys.path:
print(x)
...the folder I added to PATH does not appear (I tried adding it to the beginning and the end).
How can I use several of my user created modules together using the command prompt to import them?
Assuming you have __init__.py in your Projects folder, in the console you can do this:
import sys
sys.path.append("C:\Users\Username\Dropbox\Projects")
import Projects.MyUtilities.Utility1
Or if you want to add your desired directory permanently to the python path, you can append your directory to the value of the environment variable called PYTHONPATH.