Hvordan får jeg banen og navnet på filen som i dag utfører?

stemmer
378

Jeg har skript som kaller andre script-filer, men jeg trenger å få filbane til filen som kjører i prosessen.

For eksempel, la oss si at jeg har tre filer. Bruke execfile :

  • script_1.pysamtaler script_2.py.
  • I sin tur, script_2.pykaller script_3.py.

Hvordan kan jeg få filnavnet og banen script_3.py, fra koden iscript_3.py , uten å måtte sende denne informasjonen som argumenter fra script_2.py?

(Utføre os.getcwd()returnerer den opprinnelige start skriptet filepath ikke gjeldende filen.)

Publisert på 08/09/2008 klokken 19:41
kilden bruker
På andre språk...                            


29 svar

stemmer
464
__file__

som andre har sagt. Du kan også være lurt å bruke os.path.realpath å eliminere symlinker:

import os

os.path.realpath(__file__)
Svarte 23/12/2009 kl. 20:33
kilden bruker

stemmer
213

p1.py:

execfile("p2.py")

p2.py:

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
Svarte 08/09/2008 kl. 23:02
kilden bruker

stemmer
67

Her er et eksperiment basert på svarene i denne tråden - med Python 2.7.10 på Windows.

Stabelen-baserte seg er de eneste som synes å gi pålitelige resultater. De to siste har kortest syntaks , altså -

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

Her er til disse blir lagt til sys som fungerer! Takk til @Usagi og @pablog

Basert på følgende tre filer, og kjører script1.py fra sin mappe med python script1.py(også prøvd execfiles med absolutte stier og ringer fra en egen mappe).

C: \ TestPath \ script1.py: execfile('script2.py')
C: \ TestPath \ script2.py: execfile('lib/script3.py')
C: \ TestPath \ lib \ script3.py:

import sys
import os
import inspect

print "Python " + sys.version
print

print __file__                                        # script1.py
print sys.argv[0]                                     # script1.py
print inspect.stack()[0][1]                           # lib/script3.py
print sys.path[0]                                     # C:\testpath
print

print os.path.realpath(__file__)                      # C:\testpath\script1.py
print os.path.abspath(__file__)                       # C:\testpath\script1.py
print os.path.basename(__file__)                      # script1.py
print os.path.basename(os.path.realpath(sys.argv[0])) # script1.py
print

print sys.path[0]                                     # C:\testpath
print os.path.abspath(os.path.split(sys.argv[0])[0])  # C:\testpath
print os.path.dirname(os.path.abspath(__file__))      # C:\testpath
print os.path.dirname(os.path.realpath(sys.argv[0]))  # C:\testpath
print os.path.dirname(__file__)                       # (empty string)
print

print inspect.getfile(inspect.currentframe())         # lib/script3.py

print os.path.abspath(inspect.getfile(inspect.currentframe())) # C:\testpath\lib\script3.py
print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # C:\testpath\lib
print

print os.path.abspath(inspect.stack()[0][1])          # C:\testpath\lib\script3.py
print os.path.dirname(os.path.abspath(inspect.stack()[0][1]))  # C:\testpath\lib
print
Svarte 06/08/2015 kl. 22:50
kilden bruker

stemmer
61

Jeg tror dette er renere:

import inspect
print inspect.stack()[0][1]

og får den samme informasjonen som:

print inspect.getfile(inspect.currentframe())

Hvor [0] er den gjeldende ramme i stabelen (øverst i stabelen) og [1] er for filnavnet, økning til å gå bakover i stabelen dvs.

print inspect.stack()[1][1]

ville være filnavnet på skriptet som kalles dagens ramme. Dessuten vil bruke [-1] får deg til bunnen av stabelen, den opprinnelige kall manuset.

Svarte 08/07/2011 kl. 17:50
kilden bruker

stemmer
34
import os
os.path.dirname(__file__) # relative directory path
os.path.abspath(__file__) # absolute file path
os.path.basename(__file__) # the file name only
Svarte 06/02/2015 kl. 01:05
kilden bruker

stemmer
34

Forslagene er merket som best er sanne hvis skriptet består av bare én fil.

Hvis du ønsker å finne ut navnet på den kjørbare (dvs. root file sendes til python tolk for gjeldende program) fra en fil som kan importeres som en modul, må du gjøre dette (la oss anta at dette er i en fil heter foo.py ):

import inspect

print inspect.stack()[-1][1]

Fordi det siste ( [-1]) på stakken er det første som gikk inn i det (stabler er LIFO / FILO datastrukturer).

Deretter i filen bar.py hvis du import foovil det skrive ut bar.py , snarere enn foo.py , noe som ville være verdien av alle disse:

  • __file__
  • inspect.getfile(inspect.currentframe())
  • inspect.stack()[0][1]
Svarte 26/02/2010 kl. 22:25
kilden bruker

stemmer
13
import os
print os.path.basename(__file__)

Dette vil gi oss filnavnet bare. dvs. hvis abspath av filen er c: \ abcd \ abc.py deretter andre linjen vil skrive ut abc.py

Svarte 11/08/2013 kl. 03:05
kilden bruker

stemmer
11

Det er ikke helt klart hva du mener med "den filbane til filen som kjører i prosessen". sys.argv[0]vanligvis inneholder plasseringen av skriptet som ble påberopt av Python tolk. Sjekk sys dokumentasjon for flere detaljer.

Som @Tim og @Pat Notz har påpekt, gir __FILE__ attributt tilgang til

filen fra hvilken modulen ble lastet inn, hvis den ble lastet fra en fil

Svarte 08/09/2008 kl. 19:42
kilden bruker

stemmer
9

Jeg har et skript som må arbeide under Windows-miljø. Denne koden klippet er hva jeg er ferdig med:

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

det er ganske Hacky beslutning. Men det krever ingen eksterne biblioteker og det er det viktigste i mitt tilfelle.

Svarte 08/08/2012 kl. 09:42
kilden bruker

stemmer
8

Den __file__attributt virker både filen som inneholder den viktigste kode samt importerte moduler.

se https://web.archive.org/web/20090918095828/http://pyref.infogami.com/__file__

Svarte 08/09/2008 kl. 19:56
kilden bruker

stemmer
6
import os
os.path.dirname(os.path.abspath(__file__))

Ingen behov for å inspisere eller andre bibliotek.

Dette fungerte for meg når jeg måtte importere et script (fra en annen katalog og deretter henrettet script), som brukte en konfigurasjonsfil bosatt i samme mappe som den importerte script.

Svarte 24/06/2014 kl. 15:04
kilden bruker

stemmer
5
import sys

print sys.path[0]

dette ville skrive ut banen for tiden utfører script

Svarte 02/01/2010 kl. 18:34
kilden bruker

stemmer
5

Jeg tror det er bare __file__ Høres ut som du kan også være lurt å kassa den inspisere modulen .

Svarte 08/09/2008 kl. 19:44
kilden bruker

stemmer
4

Du kan bruke 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'
Svarte 09/09/2008 kl. 00:00
kilden bruker

stemmer
3
import sys
print sys.argv[0]
Svarte 19/04/2010 kl. 07:47
kilden bruker

stemmer
2

Dette bør fungere:

import os,sys
filename=os.path.basename(os.path.realpath(sys.argv[0]))
dirname=os.path.dirname(os.path.realpath(sys.argv[0]))
Svarte 14/06/2015 kl. 16:37
kilden bruker

stemmer
1

For å holde migrasjon konsistens på tvers av plattformer (MacOS / Windows / Linux), prøve:

path = r'%s' % os.getcwd().replace('\\','/')

Svarte 12/04/2018 kl. 05:19
kilden bruker

stemmer
1

For å få katalogen til å utføre script

 print os.path.dirname( inspect.getfile(inspect.currentframe()))
Svarte 10/05/2017 kl. 10:51
kilden bruker

stemmer
0

Siden Python tre er ganske mainstream, jeg ønsket å inkludere et pathlibsvar, som jeg tror at det er nok nå et bedre verktøy for å få tilgang til filer og baneinformasjon.

from pathlib import Path

current_file: Path = Path(__file__).resolve()

Hvis du søker katalogen av gjeldende fil, er det så enkelt som å legge .parenttil Path()uttalelse:

current_path: Path = Path(__file__).parent.resolve()
Svarte 23/08/2019 kl. 22:19
kilden bruker

stemmer
0

Her er hva jeg bruker så jeg kan kaste min kode hvor som helst uten problem. __name__er alltid definert, men __file__er bare definert når koden kjøres som en fil (for eksempel ikke i IDLE / iPython).

    if '__file__' in globals():
        self_name = globals()['__file__']
    elif '__file__' in locals():
        self_name = locals()['__file__']
    else:
        self_name = __name__

Alternativt kan dette skrives som:

self_name = globals().get('__file__', locals().get('__file__', __name__))
Svarte 28/06/2019 kl. 04:28
kilden bruker

stemmer
0
print(__file__)
print(__import__("pathlib").Path(__file__).parent)
Svarte 05/05/2019 kl. 04:19
kilden bruker

stemmer
0

Prøv dette,

import os
os.path.dirname(os.path.realpath(__file__))
Svarte 22/02/2019 kl. 17:31
kilden bruker

stemmer
0

Jeg har alltid bare brukt os funksjonen i gjeldende arbeidskatalog, eller CWD. Dette er en del av standard bibliotek og er svært enkelt å implementere. Her er et eksempel:

    import os
    base_directory = os.getcwd()
Svarte 23/01/2019 kl. 16:31
kilden bruker

stemmer
0

Enkleste måten er:

i script_1.py:

import subprocess
subprocess.call(['python3',<path_to_script_2.py>])

i script_2.py:

sys.argv[0]

PS: Jeg har prøvd execfile, men siden den leser script_2.py som en streng, sys.argv[0]returneres <string>.

Svarte 08/06/2018 kl. 12:29
kilden bruker

stemmer
0

Jeg skrev en funksjon som tar hensyn eclipse debugger og unittest . Det returnere mappe med det første manuset du starter. Du kan eventuelt angi __FILE__ var, men det viktigste er at du ikke trenger å dele denne variabelen på tvers av hele ditt kall hierarki .

Kanskje du kan håndtere andre stable spesielle tilfeller jeg ikke se, men for meg er det ok.

import inspect, os
def getRootDirectory(_file_=None):
    """
    Get the directory of the root execution file
    Can help: http://stackoverflow.com/questions/50499/how-do-i-get-the-path-and-name-of-the-file-that-is-currently-executing
    For eclipse user with unittest or debugger, the function search for the correct folder in the stack
    You can pass __file__ (with 4 underscores) if you want the caller directory
    """
    # If we don't have the __file__ :
    if _file_ is None:
        # We get the last :
        rootFile = inspect.stack()[-1][1]
        folder = os.path.abspath(rootFile)
        # If we use unittest :
        if ("/pysrc" in folder) & ("org.python.pydev" in folder):
            previous = None
            # We search from left to right the case.py :
            for el in inspect.stack():
                currentFile = os.path.abspath(el[1])
                if ("unittest/case.py" in currentFile) | ("org.python.pydev" in currentFile):
                    break
                previous = currentFile
            folder = previous
        # We return the folder :
        return os.path.dirname(folder)
    else:
        # We return the folder according to specified __file__ :
        return os.path.dirname(os.path.realpath(_file_))
Svarte 14/06/2016 kl. 15:06
kilden bruker

stemmer
0

Jeg brukte tilnærming med __FILE__
os.path.abspath(__file__)
men det er et lite triks, returnerer den .py filen når koden kjøres første gang, neste løper oppgi navn på * .pyc fil
slik at jeg bodde hos:
inspect.getfile(inspect.currentframe())
eller
sys._getframe().f_code.co_filename

Svarte 01/03/2011 kl. 09:23
kilden bruker

stemmer
-1

De fleste av disse svarene ble skrevet i Python versjon 2.x eller tidligere. I Python 3.x syntaksen for utskriftsfunksjonen er endret til å kreve parenteser, dvs. print ().

Så, dette tidligere høy score svar fra user13993 i 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

Blir i 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
Svarte 09/11/2018 kl. 01:15
kilden bruker

stemmer
-1
import os

import wx


# return the full path of this file
print(os.getcwd())

icon = wx.Icon(os.getcwd() + '/img/image.png', wx.BITMAP_TYPE_PNG, 16, 16)

# put the icon on the frame
self.SetIcon(icon)
Svarte 24/01/2013 kl. 02:43
kilden bruker

stemmer
-2

hvis du vil bare filnavn uten ./eller .pykan du prøve dette

filename = testscript.py
file_name = __file__[2:-3]

file_name vil skrive ut testscript du kan generere hva du vil ved å endre indeksen inne []

Svarte 20/01/2013 kl. 20:52
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more