Как найти исполняемый файл python

Is there a universal approach in Python, to find out the path to the file that is currently executing?

Failing approaches

path = os.path.abspath(os.path.dirname(sys.argv[0]))

This does not work if you are running from another Python script in another directory, for example by using execfile in 2.x.

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

I found that this doesn’t work in the following cases:

  • py2exe doesn’t have a __file__ attribute, although there is a workaround
  • When the code is run from IDLE using execute(), in which case there is no __file__ attribute
  • On Mac OS X v10.6 (Snow Leopard), I get NameError: global name '__file__' is not defined

Test case

Directory tree

C:.
|   a.py
---subdir
        b.py

Content of a.py

#! /usr/bin/env python
import os, sys

print "a.py: sys.argv[0]=", sys.argv[0]
print "a.py: __file__=", __file__
print "a.py: os.getcwd()=", os.getcwd()
print

execfile("subdir/b.py")

Content of subdir/b.py

#! /usr/bin/env python
import os, sys

print "b.py: sys.argv[0]=", sys.argv[0]
print "b.py: __file__=", __file__
print "b.py: os.getcwd()=", os.getcwd()
print

Output of python a.py (on Windows)

a.py: __file__= a.py
a.py: os.getcwd()= C:zzz

b.py: sys.argv[0]= a.py
b.py: __file__= a.py
b.py: os.getcwd()= C:zzz

Related (but these answers are incomplete)

  • Find path to currently running file
  • Path to current file depends on how I execute the program
  • How can I know the path of the running script in Python?
  • Change directory to the directory of a Python script

Karl Knechtel's user avatar

Karl Knechtel

61.6k11 gold badges97 silver badges147 bronze badges

asked Apr 13, 2010 at 18:37

sorin's user avatar

1

First, you need to import from inspect and os

from inspect import getsourcefile
from os.path import abspath

Next, wherever you want to find the source file from you just use

abspath(getsourcefile(lambda:0))

answered Aug 28, 2013 at 13:19

ArtOfWarfare's user avatar

ArtOfWarfareArtOfWarfare

20.3k19 gold badges131 silver badges192 bronze badges

8

You can’t directly determine the location of the main script being executed. After all, sometimes the script didn’t come from a file at all. For example, it could come from the interactive interpreter or dynamically generated code stored only in memory.

However, you can reliably determine the location of a module, since modules are always loaded from a file. If you create a module with the following code and put it in the same directory as your main script, then the main script can import the module and use that to locate itself.

some_path/module_locator.py:

def we_are_frozen():
    # All of the modules are built-in to the interpreter, e.g., by py2exe
    return hasattr(sys, "frozen")

def module_path():
    encoding = sys.getfilesystemencoding()
    if we_are_frozen():
        return os.path.dirname(unicode(sys.executable, encoding))
    return os.path.dirname(unicode(__file__, encoding))

some_path/main.py:

import module_locator
my_path = module_locator.module_path()

If you have several main scripts in different directories, you may need more than one copy of module_locator.

Of course, if your main script is loaded by some other tool that doesn’t let you import modules that are co-located with your script, then you’re out of luck. In cases like that, the information you’re after simply doesn’t exist anywhere in your program. Your best bet would be to file a bug with the authors of the tool.

answered Apr 13, 2010 at 18:48

Daniel Stutzbach's user avatar

Daniel StutzbachDaniel Stutzbach

73.6k17 gold badges88 silver badges77 bronze badges

14

This solution is robust even in executables:

import inspect, os.path

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

Peter Mortensen's user avatar

answered Jun 16, 2017 at 14:54

José Crespo Barrios's user avatar

6

I was running into a similar problem, and I think this might solve the problem:

def module_path(local_function):
   ''' returns the module path without the use of __file__.  Requires a function defined
   locally in the module.
   from http://stackoverflow.com/questions/729583/getting-file-path-of-imported-module'''
   return os.path.abspath(inspect.getsourcefile(local_function))

It works for regular scripts and in IDLE. All I can say is try it out for others!

My typical usage:

from toolbox import module_path
def main():
   pass # Do stuff

global __modpath__
__modpath__ = module_path(main)

Now I use _modpath_ instead of _file_.

Peter Mortensen's user avatar

answered Apr 21, 2011 at 19:04

Garrett Berg's user avatar

Garrett BergGarrett Berg

2,5831 gold badge22 silver badges20 bronze badges

7

You have simply called:

path = os.path.abspath(os.path.dirname(sys.argv[0]))

instead of:

path = os.path.dirname(os.path.abspath(sys.argv[0]))

abspath() gives you the absolute path of sys.argv[0] (the filename your code is in) and dirname() returns the directory path without the filename.

answered Apr 4, 2018 at 15:19

dgb's user avatar

dgbdgb

1231 silver badge4 bronze badges

1

The short answer is that there is no guaranteed way to get the information you want, however there are heuristics that work almost always in practice. You might look at How do I find the location of the executable in C?. It discusses the problem from a C point of view, but the proposed solutions are easily transcribed into Python.

Community's user avatar

answered Apr 16, 2010 at 10:28

Dale Hagglund's user avatar

Dale HagglundDale Hagglund

16k4 gold badges30 silver badges37 bronze badges

2

See my answer to the question Importing modules from parent folder for related information, including why my answer doesn’t use the unreliable __file__ variable. This simple solution should be cross-compatible with different operating systems as the modules os and inspect come as part of Python.

First, you need to import parts of the inspect and os modules.

from inspect import getsourcefile
from os.path import abspath

Next, use the following line anywhere else it’s needed in your Python code:

abspath(getsourcefile(lambda:0))

How it works:

From the built-in module os (description below), the abspath tool is imported.

OS routines for Mac, NT, or Posix depending on what system we’re on.

Then getsourcefile (description below) is imported from the built-in module inspect.

Get useful information from live Python objects.

  • abspath(path) returns the absolute/full version of a file path
  • getsourcefile(lambda:0) somehow gets the internal source file of the lambda function object, so returns '<pyshell#nn>' in the Python shell or returns the file path of the Python code currently being executed.

Using abspath on the result of getsourcefile(lambda:0) should make sure that the file path generated is the full file path of the Python file.
This explained solution was originally based on code from the answer at How do I get the path of the current executed file in Python?.

answered Nov 4, 2015 at 20:42

Edward's user avatar

EdwardEdward

1,0541 gold badge17 silver badges39 bronze badges

2

This should do the trick in a cross-platform way (so long as you’re not using the interpreter or something):

import os, sys
non_symbolic=os.path.realpath(sys.argv[0])
program_filepath=os.path.join(sys.path[0], os.path.basename(non_symbolic))

sys.path[0] is the directory that your calling script is in (the first place it looks for modules to be used by that script). We can take the name of the file itself off the end of sys.argv[0] (which is what I did with os.path.basename). os.path.join just sticks them together in a cross-platform way. os.path.realpath just makes sure if we get any symbolic links with different names than the script itself that we still get the real name of the script.

I don’t have a Mac; so, I haven’t tested this on one. Please let me know if it works, as it seems it should. I tested this in Linux (Xubuntu) with Python 3.4. Note that many solutions for this problem don’t work on Macs (since I’ve heard that __file__ is not present on Macs).

Note that if your script is a symbolic link, it will give you the path of the file it links to (and not the path of the symbolic link).

Peter Mortensen's user avatar

answered Sep 10, 2014 at 21:55

Brōtsyorfuzthrāx's user avatar

BrōtsyorfuzthrāxBrōtsyorfuzthrāx

4,3173 gold badges33 silver badges56 bronze badges

You can use Path from the pathlib module:

from pathlib import Path

# ...

Path(__file__)

You can use call to parent to go further in the path:

Path(__file__).parent

answered Oct 10, 2016 at 9:49

Gavriel Cohen's user avatar

2

Simply add the following:

from sys import *
path_to_current_file = sys.argv[0]
print(path_to_current_file)

Or:

from sys import *
print(sys.argv[0])

Papershine's user avatar

Papershine

4,9352 gold badges23 silver badges45 bronze badges

answered Nov 15, 2017 at 1:35

H. Kamran's user avatar

H. KamranH. Kamran

3662 silver badges12 bronze badges

If the code is coming from a file, you can get its full name

sys._getframe().f_code.co_filename

You can also retrieve the function name as f_code.co_name

answered Oct 25, 2018 at 8:25

Alex Cohn's user avatar

Alex CohnAlex Cohn

55.8k9 gold badges111 silver badges303 bronze badges

The main idea is, somebody will run your python code, but you need to get the folder nearest the python file.

My solution is:

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

With
os.path.dirname(os.path.abspath(__file__))
You can use it with to save photos, output files, …etc

answered Mar 31, 2019 at 15:14

ThienSuBS's user avatar

ThienSuBSThienSuBS

1,53417 silver badges26 bronze badges

1

import os
current_file_path=os.path.dirname(os.path.realpath('__file__'))

answered Apr 4, 2019 at 18:25

Mohamed.Abdo's user avatar

Mohamed.AbdoMohamed.Abdo

2,0041 gold badge19 silver badges12 bronze badges

2

How can I find the full path to the currently running Python script? That is to say, what do I have to do to achieve this:

$ pwd
/tmp
$ python baz.py
running from /tmp 
file is baz.py

codeforester's user avatar

codeforester

38.7k16 gold badges108 silver badges135 bronze badges

asked Aug 18, 2009 at 21:02

Chris Bunch's user avatar

Chris BunchChris Bunch

87.2k37 gold badges125 silver badges127 bronze badges

1

__file__ is NOT what you are looking for. Don’t use accidental side-effects

sys.argv[0] is always the path to the script (if in fact a script has been invoked) — see http://docs.python.org/library/sys.html#sys.argv

__file__ is the path of the currently executing file (script or module). This is accidentally the same as the script if it is accessed from the script! If you want to put useful things like locating resource files relative to the script location into a library, then you must use sys.argv[0].

Example:

C:junkso>type junksoscriptpathscript1.py
import sys, os
print "script: sys.argv[0] is", repr(sys.argv[0])
print "script: __file__ is", repr(__file__)
print "script: cwd is", repr(os.getcwd())
import whereutils
whereutils.show_where()

C:junkso>type python26libsite-packageswhereutils.py
import sys, os
def show_where():
    print "show_where: sys.argv[0] is", repr(sys.argv[0])
    print "show_where: __file__ is", repr(__file__)
    print "show_where: cwd is", repr(os.getcwd())

C:junkso>python26python scriptpathscript1.py
script: sys.argv[0] is 'scriptpath\script1.py'
script: __file__ is 'scriptpath\script1.py'
script: cwd is 'C:\junk\so'
show_where: sys.argv[0] is 'scriptpath\script1.py'
show_where: __file__ is 'C:\python26\lib\site-packages\whereutils.pyc'
show_where: cwd is 'C:\junk\so'

oHo's user avatar

oHo

50.6k27 gold badges163 silver badges198 bronze badges

answered Aug 19, 2009 at 1:29

John Machin's user avatar

John MachinJohn Machin

80.9k11 gold badges141 silver badges187 bronze badges

7

This will print the directory in which the script lives (as opposed to the working directory):

import os
dirname, filename = os.path.split(os.path.abspath(__file__))
print "running from", dirname
print "file is", filename

Here’s how it behaves, when I put it in c:src:

> cd c:src
> python so-where.py
running from C:src
file is so-where.py

> cd c:
> python srcso-where.py
running from C:src
file is so-where.py

answered Aug 18, 2009 at 21:08

RichieHindle's user avatar

RichieHindleRichieHindle

270k47 gold badges356 silver badges398 bronze badges

4

import sys, os

file = sys.argv[0]
pathname = os.path.dirname(file)
print 'running from %s' % os.path.abspath(pathname)
print 'file is %s' % file

Check os.getcwd() (docs)

answered Aug 18, 2009 at 21:10

Nathan's user avatar

The running file is always __file__.

Here’s a demo script, named identify.py

print __file__

Here’s the results

MacBook-5:Projects slott$ python StackOverflow/identify.py 
StackOverflow/identify.py
MacBook-5:Projects slott$ cd StackOverflow/
MacBook-5:StackOverflow slott$ python identify.py 
identify.py

answered Aug 18, 2009 at 21:10

S.Lott's user avatar

S.LottS.Lott

383k79 gold badges505 silver badges778 bronze badges

1

I would suggest

import os, sys
print os.path.split(os.path.abspath(os.path.realpath(sys.argv[0])))[0]

This way you can safely create symbolic links to the script executable and it will still find the correct directory.

answered Aug 19, 2009 at 11:24

0

The script name will (always?) be the first index of sys.argv:

import sys
print sys.argv[0]

An even easier way to find the path of your running script:

os.path.dirname(sys.argv[0])

David Mulder's user avatar

David Mulder

7,51511 gold badges45 silver badges61 bronze badges

answered Aug 18, 2009 at 21:10

WhatIsHeDoing's user avatar

WhatIsHeDoingWhatIsHeDoing

5311 gold badge6 silver badges20 bronze badges

3

The directory of the script which python is executing is added to sys.path
This is actually an array (list) which contains other paths.
The first element contains the full path where the script is located (for windows).

Therefore, for windows, one can use:

import sys
path = sys.path[0]
print(path)

Others have suggested using sys.argv[0] which works in a very similar way and is complete.

import sys
path = os.path.dirname(sys.argv[0])
print(path)

Note that sys.argv[0] contains the full working directory (path) + filename whereas sys.path[0] is the current working directory without the filename.

I have tested sys.path[0] on windows and it works. I have not tested on other operating systems outside of windows, so somebody may wish to comment on this.

answered Dec 1, 2018 at 17:06

D.L's user avatar

D.LD.L

3,9984 gold badges22 silver badges43 bronze badges

Aside from the aforementioned sys.argv[0], it is also possible to use the __main__:

import __main__
print(__main__.__file__)

Beware, however, this is only useful in very rare circumstances;
and it always creates an import loop, meaning that the __main__ will not be fully executed at that moment.

answered Oct 8, 2018 at 15:19

HoverHell's user avatar

HoverHellHoverHell

4,7193 gold badges21 silver badges23 bronze badges

Чтобы получить местоположение (путь) запущенного файла сценария в Python, используйте __file__. Это полезно для загрузки других файлов на основе местоположения запущенного файла.

До версии Python 3.8 __file__ возвращает путь, указанный при выполнении команды python (или команды python3 в некоторых средах). Если указан относительный путь, возвращается относительный путь; если указан абсолютный путь, возвращается абсолютный путь.

В Python 3.9 и более поздних версиях возвращается абсолютный путь, независимо от пути, указанного во время выполнения.

Объясняется следующее содержание.

  • os.getcwd(),__file__
  • Получить имя файла и имя каталога текущего исполняемого файла.
  • Получить абсолютный путь к выполняемому файлу.
  • Считывает другие файлы, основываясь на местоположении текущего исполняемого файла.
  • Переместить текущий каталог в каталог выполняемого файла.
  • Одна и та же обработка может быть выполнена независимо от текущего каталога во время выполнения.

Информацию о получении и изменении текущего каталога (рабочего каталога) см. в следующей статье.

  • Похожие статьи:Получение и изменение (перемещение) текущего каталога в Python

Обратите внимание, что __file__ нельзя использовать в Jupyter Notebook (.ipynb).
Каталог, в котором находится .ipynb, будет выполняться как текущий каталог, независимо от каталога, в котором запущен Jupyter Notebook.
В коде можно использовать os.chdir() для изменения текущего каталога.

Table of Contents

  • os.getcwd() и __file__.
  • Получить имя файла и имя каталога текущего исполняемого файла.
  • Получить абсолютный путь к выполняемому файлу.
  • Считывает другие файлы, основываясь на местоположении текущего исполняемого файла.
  • Переместить текущий каталог в каталог выполняемого файла.
  • Одна и та же обработка может быть выполнена независимо от текущего каталога во время выполнения.

os.getcwd() и __file__.

В Windows для проверки текущего каталога вместо pwd можно использовать команду dir.

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook

Создайте файл сценария Python (file_path.py) со следующим содержимым на нижнем уровне (datasrc).

import os

print('getcwd:      ', os.getcwd())
print('__file__:    ', __file__)

Запустите команду python (или команду python3 в некоторых средах), указав путь к файлу сценария.

python3 data/src/file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__:     data/src/file_path.py

Абсолютный путь к текущему каталогу можно получить с помощью os.getcwd(). Вы также можете использовать __file__ для получения пути, указанного командой python3.

До версии Python 3.8 __file__ будет содержать путь, указанный в команде python (или python3). В приведенном выше примере возвращается относительный путь, потому что он относительный, а абсолютный путь возвращается, если он абсолютный.

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook

python3 /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__:     /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py

Python 3.9 и более поздние версии возвращают абсолютный путь к __file__, независимо от пути, указанного в команде python (или python3).

В следующем примере мы добавим код в тот же файл сценария (file_path.py) в Python 3.7 и запустим его относительно указанного выше каталога.

В Python 3.7 используется абсолютный путь. Результаты показаны в конце этого раздела.

Получить имя файла и имя каталога текущего исполняемого файла.

Чтобы получить имя файла и имя каталога запущенного файла, используйте следующую функцию в модуле os.path стандартной библиотеки.

  • os.path.basename()
  • os.path.dirname()
print('basename:    ', os.path.basename(__file__))
print('dirname:     ', os.path.dirname(__file__))

Результат выполнения.

# basename:     file_path.py
# dirname:      data/src

Получить абсолютный путь к выполняемому файлу.

Если относительный путь получен с помощью __file__, он может быть преобразован в абсолютный с помощью os.path.abspath(). Каталоги также могут быть получены как абсолютные пути.

  • os.path.abspath() — Common pathname manipulations — Python 3.10.0 Documentation
print('abspath:     ', os.path.abspath(__file__))
print('abs dirname: ', os.path.dirname(os.path.abspath(__file__)))

Результат выполнения.

# abspath:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src

Если в os.path.abspath() указан абсолютный путь, он будет возвращен как есть. Поэтому, если __file__ является абсолютным путем, то следующие действия не приведут к ошибке.

  • os.path.abspath(__file__)

Считывает другие файлы, основываясь на местоположении текущего исполняемого файла.

Если вы хотите читать другие файлы на основе расположения (пути) выполняемого файла, объедините следующие два файла с помощью os.path.join().

  • Каталог выполняемого файла
  • Относительный путь к файлу, который будет считан из запущенного файла.

Если вы хотите прочитать файл в том же каталоге, что и запускаемый файл, просто соедините имена файлов.

print('[set target path 1]')
target_path_1 = os.path.join(os.path.dirname(__file__), 'target_1.txt')

print('target_path_1: ', target_path_1)

print('read target file:')
with open(target_path_1) as f:
    print(f.read())

Результат выполнения.

# [set target path 1]
# target_path_1:  data/src/target_1.txt
# read target file:
# !! This is "target_1.txt" !!

Верхний уровень представлен «. ». Вы можете оставить его как есть, но можете использовать os.path.normpath() для нормализации пути и удаления лишних «. » и другие символы.

  • os.path.normpath() — Common pathname manipulations — Python 3.10.0 Documentation
print('[set target path 2]')
target_path_2 = os.path.join(os.path.dirname(__file__), '../dst/target_2.txt')

print('target_path_2: ', target_path_2)
print('normalize    : ', os.path.normpath(target_path_2))

print('read target file:')
with open(target_path_2) as f:
    print(f.read())

Результат выполнения.

# [set target path 2]
# target_path_2:  data/src/../dst/target_2.txt
# normalize    :  data/dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!

Переместить текущий каталог в каталог выполняемого файла.

Используйте os.chdir() для перемещения текущего каталога в каталог файла, выполняемого в сценарии.

  • Похожие статьи:Получение и изменение (перемещение) текущего каталога в Python

Вы можете видеть, что он перемещается с помощью os.getcwd().

print('[change directory]')
os.chdir(os.path.dirname(os.path.abspath(__file__)))
print('getcwd:      ', os.getcwd())

Результат выполнения.

# [change directory]
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src

После перемещения текущего каталога нет необходимости объединять его с каталогом запущенного файла при чтении файла. Вы можете просто указать путь относительно каталога запущенного файла.

print('[set target path 1 (after chdir)]')
target_path_1 = 'target_1.txt'

print('target_path_1: ', target_path_1)

print('read target file:')
with open(target_path_1) as f:
    print(f.read())

print()
print('[set target path 2 (after chdir)]')
target_path_2 = '../dst/target_2.txt'

print('target_path_2: ', target_path_2)

print('read target file:')
with open(target_path_2) as f:
    print(f.read())

Результат выполнения.

# [set target path 1 (after chdir)]
# target_path_1:  target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2 (after chdir)]
# target_path_2:  ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!

Одна и та же обработка может быть выполнена независимо от текущего каталога во время выполнения.

Как мы показали, можно загружать файлы на основе расположения файла сценария, независимо от текущего каталога во время выполнения, используя один из следующих методов.

  • Соедините каталог запущенного файла и относительный путь к файлу, который будет считан из запущенного файла, с помощью os.path.join().
  • Переместить текущий каталог в каталог выполняемого файла.

Проще переместить текущий каталог, но, конечно, если после этого вы захотите прочитать или записать другие файлы, вам нужно будет учесть, что текущий каталог был перемещен.

Результаты предыдущих примеров обобщены ниже.

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook

python3 data/src/file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__:     data/src/file_path.py
# basename:     file_path.py
# dirname:      data/src
# abspath:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1]
# target_path_1:  data/src/target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2]
# target_path_2:  data/src/../dst/target_2.txt
# normalize    :  data/dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
# 
# [change directory]
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1 (after chdir)]
# target_path_1:  target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2 (after chdir)]
# target_path_2:  ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!

Результат указания абсолютного пути выглядит следующим образом.

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook

python3 /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__:     /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# basename:     file_path.py
# dirname:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# abspath:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1]
# target_path_1:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2]
# target_path_2:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/../dst/target_2.txt
# normalize    :  /Users/mbp/Documents/my-project/python-snippets/notebook/data/dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
# 
# [change directory]
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1 (after chdir)]
# target_path_1:  target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2 (after chdir)]
# target_path_2:  ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!

Результат перемещения текущего каталога в терминале и выполнения того же файла сценария показан ниже. Видно, что один и тот же файл может быть прочитан, даже если он выполняется из другого места.

cd data/src

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook/data/src

python3 file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# __file__:     file_path.py
# basename:     file_path.py
# dirname:      
# abspath:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1]
# target_path_1:  target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2]
# target_path_2:  ../dst/target_2.txt
# normalize    :  ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
# 
# [change directory]
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1 (after chdir)]
# target_path_1:  target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2 (after chdir)]
# target_path_2:  ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!


это может показаться вопрос новичка, но это не так. Некоторые общие подходы не работают во всех случаях:

sys.argv[0]

это означает использование path = os.path.abspath(os.path.dirname(sys.argv[0])), но это не работает, если вы работаете с другим скриптом Python в другом каталоге, и это может произойти в реальной жизни.

_ _ file__

это означает использование path = os.path.abspath(os.path.dirname(__file__)), но я обнаружил, что это не работает:

  • py2exe нет __file__ атрибут, но есть решение
  • при запуске из режима ожидания с execute() нет __file__ атрибут
  • OS X 10.6 где я получаю NameError: global name '__file__' is not defined

вопросы, связанные с неполными ответами:

  • Python-найти путь к запускаемому файлу
  • путь к текущему файлу зависит от того, как я выполнить программу
  • как узнать путь запуск скрипта на Python?
  • изменить каталог в каталог скрипта Python

Я ищу универсального решения, которая будет работать во всех вышеперечисленных случаях использовать.

обновление

вот результат теста:

вывод python a.py (on Windows)

a.py: __file__= a.py
a.py: os.getcwd()= C:zzz

b.py: sys.argv[0]= a.py
b.py: __file__= a.py
b.py: os.getcwd()= C:zzz

а.ру

#! /usr/bin/env python
import os, sys

print "a.py: sys.argv[0]=", sys.argv[0]
print "a.py: __file__=", __file__
print "a.py: os.getcwd()=", os.getcwd()
print

execfile("subdir/b.py")

subdir/b.py

#! /usr/bin/env python
import os, sys

print "b.py: sys.argv[0]=", sys.argv[0]
print "b.py: __file__=", __file__
print "b.py: os.getcwd()=", os.getcwd()
print

дерево

C:.
| a.py
---subdir
b.py


1263  


10  

10 ответов:

вы не можете напрямую определить местоположение основного выполняемого скрипта. В конце концов, иногда сценарий вообще не исходил из файла. Например, он может исходить из интерактивного интерпретатора или динамически генерируемого кода, хранящегося только в памяти.

тем не менее, вы можете надежно определить местоположение модуля, так как модули всегда загружаются из файла. Если вы создадите модуль со следующим кодом и поместите его в тот же каталог, что и ваш основной скрипт, то основной скрипт может импортировать модуль и использовать его, чтобы найти себя.

some_path/module_locator.py:

def we_are_frozen():
    # All of the modules are built-in to the interpreter, e.g., by py2exe
    return hasattr(sys, "frozen")

def module_path():
    encoding = sys.getfilesystemencoding()
    if we_are_frozen():
        return os.path.dirname(unicode(sys.executable, encoding))
    return os.path.dirname(unicode(__file__, encoding))

some_path/main.py:

import module_locator
my_path = module_locator.module_path()

Если у вас есть несколько основных скриптов в разных каталогах, вам может понадобиться более одной копии module_locator.

конечно, если ваш основной скрипт загружен каким-то другим инструментом, который не позволяет вам импортировать модули, которые расположены вместе с вашим скриптом, то вам не повезло. В подобных случаях информация, которую вы ищете, просто не существует нигде в вашей программе. Лучше всего было бы подать ошибку с авторами инструмента.

во-первых, вам нужно импортировать из inspect и os

from inspect import getsourcefile
from os.path import abspath

далее, везде, где вы хотите найти исходный файл от вас просто использовать

abspath(getsourcefile(lambda:0))

я столкнулся с подобной проблемой, и я думаю, что это может решить проблему:

def module_path(local_function):
   ''' returns the module path without the use of __file__.  Requires a function defined
   locally in the module.
   from http://stackoverflow.com/questions/729583/getting-file-path-of-imported-module'''
   return os.path.abspath(inspect.getsourcefile(local_function))

Он работает для обычных скриптов и в режиме ожидания. Все, что я могу сказать, это попробовать его на других!

Мое типичное использование:

from toolbox import module_path
def main():
   pass # Do stuff

global __modpath__
__modpath__ = module_path(main)

сейчас я использую __MODPATH выступает__ вместо __файл__.

короткий ответ:нет гарантированного способа получить нужную вам информацию, однако, есть эвристики, которые работают почти всегда на практике. Вы можете посмотреть на как найти расположение исполняемого файла в C?. Он обсуждает проблему с точки зрения C, но предлагаемые решения легко транскрибируются на Python.

это решение надежно даже в исполняемых файлах

import inspect, os.path

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

смотрите мой ответ на вопрос импорт модулей из родительской папки для соответствующей информации, в том числе почему мой ответ не использует ненадежный __file__ переменной. Это простое решение должно быть кросс-совместимо с различными операционными системами в качестве модулей os и inspect приходите как часть Python.

во-первых, вам нужно импортировать части проверить и os модули.

from inspect import getsourcefile
from os.path import abspath

далее использовать следующая строка в любом другом месте это необходимо в вашем коде Python:

abspath(getsourcefile(lambda:0))

как работает:

из встроенного модуля os (описание ниже) импортируется.

процедуры ОС для Mac, NT или Posix в зависимости от того, на какой системе мы находимся.

затем getsourcefile (описание ниже) импортируется из встроенного модуля inspect.

получить полезную информацию от live Python объекты.

  • abspath(path) возвращает абсолютную / полную версию пути к файлу
  • getsourcefile(lambda:0) каким-то образом получает внутренний исходный файл объекта лямбда-функции, поэтому возвращает '<pyshell#nn>' в оболочке Python или возвращает путь к файлу текущего выполняемого кода Python.

используя abspath в результате getsourcefile(lambda:0) должен убедиться, что созданный путь к файлу является полным путем к файлу Python.
Это объяснило решение изначально было основано на коде из ответа по адресу как получить путь к текущему исполняемому файлу в Python?.

это должно сделать трюк кросс-платформенным способом (пока вы не используете интерпретатор или что-то еще):

import os, sys
non_symbolic=os.path.realpath(sys.argv[0])
program_filepath=os.path.join(sys.path[0], os.path.basename(non_symbolic))

sys.path[0] — это каталог, в котором находится вызывающий скрипт (в первую очередь он ищет модули, которые будут использоваться этим скриптом). Мы можем взять имя самого файла в конце sys.argv[0] (что я и сделала с os.path.basename). os.path.join просто склеивает их вместе кросс-платформенным способом. os.path.realpath просто убедитесь, что мы получаем какие-либо символические ссылки с разными имена, чем сам скрипт, что мы все еще получаем настоящее имя скрипта.

у меня нет Mac; так что, я не проверял это на одном. Пожалуйста, дайте мне знать, если это работает, как кажется, это должно быть. Я тестировал это в Linux (Xubuntu) с Python 3.4. Обратите внимание, что многие решения этой проблемы не работают на Mac (так как я слышал, что __file__ нет на Macs).

обратите внимание, что если ваш скрипт является символической ссылкой, он даст вам путь к файлу, на который он ссылается (а не путь символической ссылки).

можно использовать Path С pathlib модуль:

from pathlib import Path

# ...

Path(__file__)

вы можете использовать вызов parent чтобы идти дальше по пути:

Path(__file__).parent

вы просто позвонили:

path = os.path.abspath(os.path.dirname(sys.argv[0]))

вместо:

path = os.path.dirname(os.path.abspath(sys.argv[0]))

abspath() дает вам абсолютный путь sys.argv[0] (имя файла, в котором находится ваш код) и dirname() возвращает путь без имени файла.

просто добавьте следующее:

from sys import *
path_to_current_file = sys.argv[0]
print(path_to_current_file)

или:

from sys import *
print(sys.argv[0])

Иногда бывает важно узнать где лежит исполняемый файл языка программирования Python, который мы запускаем.

Частая задача, которая возникает при конфигурировании сервера. 

Для unix подобных систем мы можем воспользоваться командой 

which имя_команды

В Windows аналогом этой команды является команда

where имя_команды

Так мы тоже можем узнать где лежит исполняемый файл. Таким образом можно находить исполняемый файл, который запускает при запуске python.

  • Комментарии
  • Отзывы

Понравилась статья? Поделить с друзьями:

Не пропустите также:

  • Как через tga найти угол a
  • Как найти комнату в jackbox fun
  • Как найти форму слова пример
  • Как найти частоту волны на радио
  • Как найти большее основание ромба

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии