How do I get the path and name of the file that is currently executing?

后端 未结 29 2336
你的背包
你的背包 2020-11-22 06:43

I have scripts calling other script files but I need to get the filepath of the file that is currently running within the process.

For example, let\'s say I have th

相关标签:
29条回答
  • 2020-11-22 07:13

    Most of these answers were written in Python version 2.x or earlier. In Python 3.x the syntax for the print function has changed to require parentheses, i.e. print().

    So, this earlier high score answer from user13993 in Python 2.x:

    import inspect, os
    print inspect.getfile(inspect.currentframe()) # script filename (usually with path)
    print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # script directory
    

    Becomes in Python 3.x:

    import inspect, os
    print(inspect.getfile(inspect.currentframe())) # script filename (usually with path)
    print(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) ) # script directory
    
    0 讨论(0)
  • 2020-11-22 07:14

    Update 2018-11-28:

    Here is a summary of experiments with Python 2 and 3. With

    main.py - runs foo.py
    foo.py - runs lib/bar.py
    lib/bar.py - prints filepath expressions

    | Python | Run statement       | Filepath expression                    |
    |--------+---------------------+----------------------------------------|
    |      2 | execfile            | os.path.abspath(inspect.stack()[0][1]) |
    |      2 | from lib import bar | __file__                               |
    |      3 | exec                | (wasn't able to obtain it)             |
    |      3 | import lib.bar      | __file__                               |
    

    For Python 2, it might be clearer to switch to packages so can use from lib import bar - just add empty __init__.py files to the two folders.

    For Python 3, execfile doesn't exist - the nearest alternative is exec(open(<filename>).read()), though this affects the stack frames. It's simplest to just use import foo and import lib.bar - no __init__.py files needed.

    See also Difference between import and execfile


    Original Answer:

    Here is an experiment based on the answers in this thread - with Python 2.7.10 on Windows.

    The stack-based ones are the only ones that seem to give reliable results. The last two have the shortest syntax, i.e. -

    print os.path.abspath(inspect.stack()[0][1])                   # C:\filepaths\lib\bar.py
    print os.path.dirname(os.path.abspath(inspect.stack()[0][1]))  # C:\filepaths\lib
    

    Here's to these being added to sys as functions! Credit to @Usagi and @pablog

    Based on the following three files, and running main.py from its folder with python main.py (also tried execfiles with absolute paths and calling from a separate folder).

    C:\filepaths\main.py: execfile('foo.py')
    C:\filepaths\foo.py: execfile('lib/bar.py')
    C:\filepaths\lib\bar.py:

    import sys
    import os
    import inspect
    
    print "Python " + sys.version
    print
    
    print __file__                                        # main.py
    print sys.argv[0]                                     # main.py
    print inspect.stack()[0][1]                           # lib/bar.py
    print sys.path[0]                                     # C:\filepaths
    print
    
    print os.path.realpath(__file__)                      # C:\filepaths\main.py
    print os.path.abspath(__file__)                       # C:\filepaths\main.py
    print os.path.basename(__file__)                      # main.py
    print os.path.basename(os.path.realpath(sys.argv[0])) # main.py
    print
    
    print sys.path[0]                                     # C:\filepaths
    print os.path.abspath(os.path.split(sys.argv[0])[0])  # C:\filepaths
    print os.path.dirname(os.path.abspath(__file__))      # C:\filepaths
    print os.path.dirname(os.path.realpath(sys.argv[0]))  # C:\filepaths
    print os.path.dirname(__file__)                       # (empty string)
    print
    
    print inspect.getfile(inspect.currentframe())         # lib/bar.py
    
    print os.path.abspath(inspect.getfile(inspect.currentframe())) # C:\filepaths\lib\bar.py
    print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # C:\filepaths\lib
    print
    
    print os.path.abspath(inspect.stack()[0][1])          # C:\filepaths\lib\bar.py
    print os.path.dirname(os.path.abspath(inspect.stack()[0][1]))  # C:\filepaths\lib
    print
    
    0 讨论(0)
  • 2020-11-22 07:14
    import os
    os.path.dirname(os.path.abspath(__file__))
    

    No need for inspect or any other library.

    This worked for me when I had to import a script (from a different directory then the executed script), that used a configuration file residing in the same folder as the imported script.

    0 讨论(0)
  • 2020-11-22 07:14

    I have always just used the os feature of Current Working Directory, or CWD. This is part of the standard library, and is very easy to implement. Here is an example:

        import os
        base_directory = os.getcwd()
    
    0 讨论(0)
  • 2020-11-22 07:16

    I have a script that must work under windows environment. This code snipped is what I've finished with:

    import os,sys
    PROJECT_PATH = os.path.abspath(os.path.split(sys.argv[0])[0])
    

    it's quite a hacky decision. But it requires no external libraries and it's the most important thing in my case.

    0 讨论(0)
  • 2020-11-22 07:16

    You can use inspect.stack()

    import inspect,os
    inspect.stack()[0]  => (<frame object at 0x00AC2AC0>, 'g:\\Python\\Test\\_GetCurrentProgram.py', 15, '<module>', ['print inspect.stack()[0]\n'], 0)
    os.path.abspath (inspect.stack()[0][1]) => 'g:\\Python\\Test\\_GetCurrentProgram.py'
    
    0 讨论(0)
提交回复
热议问题