How to properly determine current script directory?

I would like to see what is best way to determine current script directory in python?

I discovered that two to the many ways of calling python code, it is hard to find a good solution.

Here are some problems:

  • __file__ is not defined if the script is executed with exec , execfile
  • __module__ is defined only in modules
  • Use cases:

  • ./myfile.py
  • python myfile.py
  • ./somedir/myfile.py
  • python somedir/myfile.py
  • execfile('myfile.py') (from another script, that can be located in another directory and that can have another current directory.
  • I know that there is no perfect solution, because in some cases but I'm looking for the best approach that solved most of the cases.

    The most used approach is os.path.dirname(os.path.abspath(__file__)) but this really doesn't work if you execute the script from another one with exec() .

    Warning

    Any solution that uses current directory will fail, this can be different based on the way the script is called or it can be changed inside the running script.


    os.path.dirname(os.path.abspath(__file__))
    

    is indeed the best you're going to get.

    It's unusual to be executing a script with exec / execfile ; normally you should be using the module infrastructure to load scripts. If you must use these methods, I suggest setting __file__ in the globals you pass to the script so it can read that filename.

    There's no other way to get the filename in execed code: as you note, the CWD may be in a completely different place.


    If you really want to cover the case that a script is called via execfile(...) , you can use the inspect module to deduce the filename (including the path). As far as I am aware, this will work for all cases you listed:

    filename = inspect.getframeinfo(inspect.currentframe()).filename
    path = os.path.dirname(os.path.abspath(filename))
    

    #!/usr/bin/env python
    import inspect
    import os
    import sys
    
    def get_script_dir(follow_symlinks=True):
        if getattr(sys, 'frozen', False): # py2exe, PyInstaller, cx_Freeze
            path = os.path.abspath(sys.executable)
        else:
            path = inspect.getabsfile(get_script_dir)
        if follow_symlinks:
            path = os.path.realpath(path)
        return os.path.dirname(path)
    
    print(get_script_dir())
    

    It works on CPython, Jython, Pypy. It works if the script is executed using execfile() ( sys.argv[0] and __file__ -based solutions would fail here). It works if the script is inside an executable zip file (/an egg). It works if the script is "imported" ( PYTHONPATH=/path/to/library.zip python -mscript_to_run ) from a zip file; it returns the archive path in this case. It works if the script is compiled into a standalone executable ( sys.frozen ). It works for symlinks ( realpath eliminates symbolic links). It works in an interactive interpreter; it returns the current working directory in this case.

    链接地址: http://www.djcxy.com/p/9282.html

    上一篇: 如何知道/更改Python shell中的当前目录?

    下一篇: 如何正确确定当前脚本目录?