Locking on file locations in a large Python project - python

When a Python project gets big, certain code segments, such as utility functions, tend to be run from various locations:
from a __main__
from a django server process
from a test in a test suite
In each case the working directory for the python interpreter may be different and assuming the project spans over a sub-directory tree, the following line doesn't always work:
with open('some_file.xml','r') as my_xml:
It doesn't work because some_file.xml isn't always in your working directory. You need to be specific regarding the file's location, however, the project may be deployed in various environments so simply adding the directory to the open statement isn't a good solution.
What would be an elegant and efficient way to "lock on" the location of the file throughout the project?

using the following variable to get the directory of the project may help
__file__
How to make a python program path independent?

Related

How do programs know where their files are? And how to implement the same thing in python?

I am working on a python project that depends on some other files. It all works fine while testing. However, I want the program to run on start up. The working directory for programs that run on start up seems to be C:Windows\system32. When installing a program, it usually asks where to install it and no matter where you put it, if it runs on start up, it knows where its files are located. How do they achieve that? Also, how to achieve the same thing in python?
First of all, what do you mean by "their files"? Windows applications can store "their files" in multiple places (including but not limited to %CommonProgramFiles%, %ProgramData% and %AppData%).
That being said, the common location for simple applications and scripts is to use the same directory as the .exe (or script).
In Python there seems to be multiple ways to find this path, this seems to work nicely:
import os
print(os.path.abspath(os.path.dirname(__file__)))
See also:
How do I get the path of the Python script I am running in?
How do I get the path and name of the file that is currently executing?
If you plan to consume local files that contain raw data or processed data, defining a default directory or a set of directories can simplify your implementation, for example:
Place your data files under a specific set of folders in C:\ or place your files under the F:\ folder, that can be a part of your on premisses file system
Based on where your Python application is located, you'll need to use relative paths or a library to help you to locate these files.
Here are some examples:
os.path
pathlib

How to deal with working on one project on different machines (paths)?

This is my first time coding a "project" (something more than solving exercises in single files). A number of my .py files have variables imported from a specific path. I also have a main "Run" file where I import things I've written in other files and execute the project as a whole.
Recently I've started working on this project on several different machines (home, work, laptop etc) and have just started learning how to use GitHub.
My question is, how do I deal with the fact that every time I open up my code on a different machine I need to go around changing all the paths to fit the new machine, and then change them back again when I'm home? I started writing a Run file for each location I work at so that my sys.path commands are ok with that machine, but it doesn't solve the problem of my other modules importing variables from specific paths that vary from machine to machine. Is there a way round this or is the problem in how I'm setting up the project itself?
In an ideal world it would all just work without me having to change something before I run, depending on the machine I'm working on, but I don't know if that's possible.
My current thoughts are whether there is some command I'm not aware of that can set variables inside a .py file from my main Run.py file - that way I can just have a run file for each machine.
Any suggestions are gladly taken! Whatever it is, it must be better than commenting back in the correct file path each time I open it on a different machine!
You should always use relative paths, not static which I assume you have got.
Assuming your in an index file and you need to access images folder, you probably have something like /users/username/project/images/image.png
Instead you want something like ../images/image.png, this tells your index file to go backwards one folder to say the root of the project, then proceed into our images folder etc.
Relative paths mean you create a path from where your file exists, and not an entire path from ground up.
You need to identify all your setting that are hardcoded in your project, and make them relative to your current workspace. This is a common problem.
Also if you are using python, make sure that you do not hardcode the path to files in string, but instead that you use the proper system api:
os.path.join('file','to','your','ressource')
that will be computed differently if you are on unix or windows.

Starting a python script on boot (startx) with an absolute path, in which there are relative paths

I realise this question may already exist, but the answers I've found haven't worked and I have a slightly different setup.
I have a python file /home/pi/python_games/frontend.py that I am trying to start when lxde loads by placing #python /home/pi/python_games/frontend.py in /etc/xdg/lxsession/LXDE/autostart.
It doesn't run and there are no error messages.
When trying to run python /home/pi/python_games/frontend.py, python complains about not being able to find the files that are loaded using relative links eg: /home/pi/python_games/image.png is called with image.png. Obviously one solution would be to give these resources absolute paths, but the python program also calls other python programs in its directory that also have relative paths, and I don't want to go changing all them.
Anyone got any ideas?
Thanks
Tom
you could change your current working directory inside the script before you start calling your relative imports, use os.chdir("absolute path on where your script lives").
Rather than change your current working directory, in yourfrontend.pyscript you could use the value of the predefined__file__module attribute, which will be the absolute pathname of the script file, to determine absolute paths to the other files in the same directory.
Functions in theos.pathmodule, such assplit()andjoin(), will make doing this fairly easy.

How to put files in folders using py2exe.

Hi!I made a chess engine in python which i then compiled to .exe using py2exe. The problem is that it doesn't look very neat when i have all the strange files gathered together in the same folder (dist). I'd like to make a new folder inside the dist folder that contains all the helper files, so all my dist folder contains is the folder holding the helper files and the main launch application. However, i can't simply copy the helper files to a new folder, as the computer doesn't find them then and raises an error.
How can it be solved? Also, i'm using inno setup to make an installation, but i can't figure out how to find a solution there, either.
Thank you very much!
There is a feature in the configuration of py2exe that allows you to bundle all the Python files in a single library.zip file. That would considerably reduce the amount of files in the root directory, but there will still remain some files, regardless of all that.
These files are generally DLL files, at least from what I saw with GUI applications. You cannot remove these, because they are required to launch the application. A workaround to this problem is to create a batch file that will run the actual program which can be in child directory. The point is that these files should either be in the same directory as the executable, or the current working directory, or a path in the PATH environment variable. At least it's the case of most of these. Another approach might be a batch file which will modify the PATH variable or cd to another directory and run the file afterwards
I never tried to do it, so it might break some things for you. Anyway, IMO the best approach is to create an installer and add shortcuts and you won't have to bother with the user messing with these files.
Try using pyinstaller instead. It's easy to use, and will compile your PythonLib and all necessary python files to a stand alone EXE. So you don't have to worry about the having a mess of files in your dist file. (just one single exe).
And if you have other external files, such as databases, text files, csv's. etc... you can set them up to deploy in exactly the fashion you want from the inno setup [Files] section.
I wrote a detailed explanation on this yesterday, so check out this link:
https://stackoverflow.com/a/13259452/1339024
--Edit--
*Make sure you use pyinstaller 1.5 , as the 2.x version doesn't exactly work the same

Opening various main.py files in Eclipse without creating a new project

I have a python project developed in eclipse. Independantly there are various data directories in various locations and it is desirable to operate on each with a different main.py that imports the python project. If I store a main.py with my data, how can I open it in eclipse and run the debugger?
I can run ipython in each directory without a problem; but, I am not clear on how to move between different main.py files within eclipse. The run configuration does allow you to go outside the project and I would prefer not having to change this each time anyway. Any insight would be great!
You could do this by setting up each main.py + data directory as its own Eclipse project, each with a custom run/debug configuration. You do have extra projects, but they don't require any ongoing maintenance.
After the initial setup, you continue work on the real python project and debugging any given data directory consists of selecting the appropriate project and invoking the debugger. Not maximally elegant, but not bad.
If you're truly loath to make new projects, you could bring the main.py files into the project and store the location of the associated data directory inside each of them. Each main begins by changing to the data directory, and then runs as usual. In eclipse you set up multiple run configurations, one for each main.py which you can then run without any extra tinkering.
It is inelegant and fragile to keep the data directory information inside each main.py, but maybe better for your purposes.

Categories