Track change accounting

On another question , how do you identify paths that might change? For example, if a program calls a file in the same directory as the program, you can simply use the path ". \ Foo.py" in * nix. However, apparently Windows likes the path to be hardcoded, for example. "C: \ Python_project \ foo.py".

What happens if the path changes? For example, the file might not be on the C: drive, but on a flash drive or external drive, which might change the drive letter. The file can still be in the same directory as the program, but it won't match the drive letter in the code.

I want the program to be cross platform, but I expect that I might have to use os.name or something to figure out which path code block to use.

+1


source to share


4 answers


Simple answer: you define an absolute path based on the environment.

What you really need is some pointers. There are various bits of runtime and environment information that you can collect from various places in the standard library (and they certainly help me when I want to deploy my application to windows).

So first, some general things:

  • os.path

    is a standard library module with many cross-platform manipulations. Your best friend. "Follow os.path" which I once read in a book.
  • __file__

    - Location of the current module.
  • sys.executable

    - Location of running Python.

Now you can pretty much pick whatever you want from these three sources. The functions from os.path will help you traverse the tree:

  • os.path.join('path1', 'path2')

    - combine route segments in a cross-platform way.
  • os.path.expanduser('a_path')

    - find the path a_path

    in the user's home directory
  • os.path.abspath('a_path')

    - convert relative path to absolute path
  • os.path.dirname('a_path')

    - get the directory the path is in
  • many other...


So, combining this for example:

# script1.py
# Get the path to the script2.py in the same directory
import os
this_script_path = os.path.abspath(__file__)
this_dir_path = os.path.dirname(this_script_path)
script2_path = os.path.join(this_dir_path, 'script2.py')
print script2_path

      

And by running it:

ali@work:~/tmp$ python script1.py 
/home/ali/tmp/script2.py

      

Now, for your particular case, it seems like you are a little confused about the concept of "working directory" and "directory where the script resides". They can be the same, but they can also be different. For example, the "working directory" can be changed so that the functions that use it may find what they are looking for sometimes, but not others. subprocess.Popen

is an example of this.

If you always walk the path absolutely, you will never run into problems with working directories.

+4


source


If your file is always in the same directory as your program, follow these steps:

def _isInProductionMode():
    """ returns True when running the exe, 
        False when running from a script, ie development mode.
    """
    return (hasattr(sys, "frozen") or # new py2exe
           hasattr(sys, "importers") # old py2exe
           or imp.is_frozen("__main__")) #tools/freeze

def _getAppDir():
    """ returns the directory name of the script or the directory 
        name of the exe
    """
    if _isInProductionMode():
        return os.path.dirname(sys.executable)
    return os.path.dirname(__file__)

      



must work. Also, I have used py2exe for my own application and have not tested it with other exe conversion applications.

0


source


What exactly do you mean by "calling the file ... foo.py"?

  • Import? If so, the path is completely outside of your program. Set the environment variable PYTHONPATH

    with .

    or c:\

    or at the shell level. For example, you can write scripts with two shell lines to set an environment variable and run Python.

    Window

    SET PYTHONPATH=C:\path\to\library
    python myapp.py
    
          

    Linux

    export PYTHONPATH=./relative/path
    python myapp.py
    
          

  • ExecFile? Consider using imports.

  • Read and Eval? Consider using imports.

If the PYTHONPATH is too complex, then put your module in the Python lib / site-packages directory, where it will be placed in the PYTHONPATH by default.

0


source


I figured it out using os.getcwd () . I also learned about using os.path.join to automatically detect the correct path format based on OS. Here's the code:

def openNewRecord(self, event): # wxGlade: CharSheet.<event_handler>
    """Create a new, blank record sheet."""
    path = os.getcwd()
    subprocess.Popen(os.path.join(path, "TW2K_char_rec_sheet.py"), shell=True).stdout

      

It seems to work. Thanks for the ideas.

-1


source







All Articles