मुझे उस फ़ाइल का पथ और नाम कैसे मिलेगा जो वर्तमान में निष्पादित हो रहा है?


482

मेरे पास अन्य स्क्रिप्ट फ़ाइलों को कॉल करने वाली स्क्रिप्ट्स हैं, लेकिन मुझे उस फ़ाइल की फ़ाइलपथ प्राप्त करने की आवश्यकता है जो वर्तमान में प्रक्रिया के भीतर चल रही है।

उदाहरण के लिए, मान लें कि मेरे पास तीन फाइलें हैं। निष्पादन योग्य का उपयोग करना :

  • script_1.pyकॉल करता है script_2.py
  • बदले में, script_2.pyकॉलscript_3.py

मैं कैसे फ़ाइल नाम और के पथ प्राप्त कर सकते हैं script_3.py, के भीतर कोड सेscript_3.py से तर्क के रूप में है कि जानकारी पारित करने के लिए बिना, script_2.py?

(निष्पादित os.getcwd()करना मूल आरंभ स्क्रिप्ट की फ़ाइलपथ को वर्तमान फ़ाइल की नहीं लौटाता है।)



2
os.path.realpath ( फ़ाइल )
गिरीश गुप्ता

जवाबों:


256

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

11
BEWARE: यह कॉल विभिन्न वातावरणों के साथ एक ही परिणाम नहीं देता है। Usagi के उत्तर को नीचे स्वीकार करने पर विचार करें: stackoverflow.com/a/6628348/851398
faraday

3
@faraday: क्या आप एक उदाहरण प्रदान कर सकते हैं? मैंने इसी तरह के प्रश्न का उपयोग करकेinspect.getabsfile() उत्तर दिया है और यह उन सभी मामलों के लिए काम करता है जो मैंने कोशिश की हैं।
17

1
क्या वाकई @Usagi जवाब बेहतर है?
Dror

4
nah user13993 ने इसे कहीं ज्यादा बेहतर बताया
osirisgothra

6
user13993 ने वास्तव में इसे नंगा किया था। होना चाहिएos.path.realpath(__file__)
uchuugaka

565
__file__

जैसा कि दूसरों ने कहा है। सीमलिंक को खत्म करने के लिए आप os.path.realpath का उपयोग करना चाह सकते हैं :

import os

os.path.realpath(__file__)

14
इस दृष्टिकोण से सावधान रहने की आवश्यकता है क्योंकि कभी-कभी __file__'script_name.py', और अन्य समय 'script_name.pyc' वापस आ जाता है। इसलिए आउटपुट स्थिर नहीं है।
मेकट्रोनर

27
लेकिन जब से हम केवल इस फ़ाइल के पथ का उपयोग कर रहे हैं जो अप्रासंगिक है।
उवे कोलोसका

5
यह अजीब है: जब "__file__"उद्धरण (स्ट्रिंग के रूप में) में कमांड लाइन से चल रहा है, तो वह dir देता है जिसमें से cmd चलाया जाता है, लेकिन __file__ (उद्धरण के बिना स्रोत फ़ाइल को पथ देता है ... ऐसा क्यों है
muon

7
@ muon इस बात पर कोई जांच नहीं करता है कि फ़ाइल नाम स्ट्रिंग में मौजूद है या नहीं, और चूंकि फ़ाइल पथ cwd के सापेक्ष हैं, इसलिए यह है कि os.path.realpathफ़ंक्शन dirपथ के भाग को मानता है। os.path.dirname(os.path.realpath(__file__))फ़ाइल के साथ निर्देशिका देता है। os.path.dirname(os.path.realpath("__file__"))रिटर्न cwd। os.path.dirname(os.path.realpath("here_be_dragons"))cwd भी देता है।
जेमी बुल

86

अपडेट 2018-11-28:

यहाँ पायथन 2 और 3. के साथ प्रयोगों का सारांश दिया गया है

main.py - foo.py foo.py चलाता है
- lib / bar.py
lib / bar.py - prints filepath अभिव्यक्त करता है

| 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__                               |

पायथन 2 के लिए, पैकेजों पर स्विच करने के लिए यह स्पष्ट हो सकता है ताकि उपयोग कर सकें from lib import bar- बस __init__.pyदो फ़ोल्डरों में खाली फाइलें जोड़ें ।

पायथन 3 के लिए, execfileमौजूद नहीं है - निकटतम विकल्प है exec(open(<filename>).read()), हालांकि यह स्टैक फ्रेम को प्रभावित करता है। यह सिर्फ उपयोग करने के लिए सबसे सरल है import fooऔर import lib.bar- कोई __init__.pyफ़ाइलों की आवश्यकता नहीं है।

आयात और निष्पादन के बीच अंतर भी देखें


मूल उत्तर:

इस धागे में उत्तरों पर आधारित एक प्रयोग है - विंडोज पर पायथन 2.7.10 के साथ।

स्टैक-आधारित केवल वही हैं जो विश्वसनीय परिणाम देते हैं। अंतिम दो में सबसे छोटा वाक्यविन्यास है , -

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

यहाँ इन कार्यों के रूप में sys में जोड़ा जा रहा है! इसका श्रेय @Usagi और @pablog को दिया जाएगा

निम्न तीन फ़ाइलों के आधार पर, और अपने फोल्डर से मेनफ्रेम चला रहा है python main.py(निरपेक्ष रास्तों के साथ निष्पादन की कोशिश करता है और एक अलग फ़ोल्डर से कॉल करता है)।

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

72

मुझे लगता है कि यह क्लीनर है:

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

और जैसी जानकारी मिलती है:

print inspect.getfile(inspect.currentframe())

जहां [0] स्टैक में मौजूदा फ्रेम (स्टैक के ऊपर) और [1] फ़ाइल नाम के लिए है, स्टैक में पीछे की ओर जाने के लिए वृद्धि।

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

स्क्रिप्ट का फ़ाइल नाम होगा जिसे वर्तमान फ़्रेम कहा जाता है। इसके अलावा, [-1] का उपयोग करने से आपको स्टैक के निचले भाग में मूल कॉलिंग स्क्रिप्ट मिल जाएगी।


4
टपल के अंदर की स्थिति पर भरोसा करने की सलाह न दें। यह बिल्कुल स्पष्ट नहीं है कि कोड पढ़ते समय आप किस डेटा को प्राप्त करने की कोशिश कर रहे हैं।
jpmc26

5
inspect.getfile()__file__मॉड्यूल ऑब्जेक्ट पास होने पर विशेषता देता है । inspect.currentframe()मॉड्यूल लौटाता है। एर्गो, यह कहने का एक महंगा तरीका है __file__
मार्टिन पीटर्स

inspect.stack()एक बहुत महंगा कार्य है, बस से अधिक है inspect.currentframe(), और यह भी inspect.getfile()एक मॉड्यूल वस्तु पर कॉल करता है।
मार्टिन पीटर्स

42
import os
os.path.dirname(__file__) # relative directory path
os.path.abspath(__file__) # absolute file path
os.path.basename(__file__) # the file name only

1
मैंने अभी @Pat Notz की टिप्पणी की कोशिश की। मुझे लगता है कि आप बस के माध्यम से फ़ाइल नाम प्राप्त कर सकते हैं __file__
17-28 में hlin117

Python3 में, os.path.dirnameआपको वह रिश्तेदार पथ देगा जहाँ से आप स्क्रिप्ट चला रहे हैं। में जैसे हो जाएगा और स्क्रिप्ट के लिए नहीं निरपेक्ष पथ। मुझे एब्सपैथ की तलाश थी लेकिन स्क्रिप्ट का नाम हटा देना। Sys.path का पहला तत्व स्पष्ट रूप से उत्तर है । python ../../test.pyos.path.dirname../../sys.path[0]
एयरमैन

37

यदि आपकी स्क्रिप्ट में केवल एक फ़ाइल शामिल है, तो सबसे अच्छे के रूप में चिह्नित सुझाव सभी सत्य हैं।

यदि आप निष्पादन योग्य (यानी मौजूदा प्रोग्राम के लिए अजगर इंटरप्रेटर के लिए रूट फाइल को पास करना चाहते हैं) एक मॉड्यूल से आयात की जा सकने वाली फ़ाइल का पता लगाना चाहते हैं, तो आपको ऐसा करने की आवश्यकता है (मान लें कि यह एक फ़ाइल में है foo.py नाम दिया गया है :

import inspect

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

क्योंकि [-1]स्टैक पर आखिरी चीज ( ) पहली चीज है जो इसमें चली गई (ढेर LIFO / FILO डेटा संरचनाएं हैं)।

फिर फ़ाइल में bar.py यदि आप import fooइसे प्रिंट करेंगे bar.py बजाय, foo.py , जो इन सभी का मान होगा:

  • __file__
  • inspect.getfile(inspect.currentframe())
  • inspect.stack()[0][1]

यह ग्रहण पर इकाई परीक्षण के लिए अच्छी तरह से नहीं बल्कि काम करता है, मैं /home/user/Softwares/eclipse/plugins/org.python.pydev_4.5.5.201603221110/pysrc मिला
hayj

2
यह sys.modules['__main__'].__file__वास्तव में वर्तनी का एक महंगा तरीका है ।
मार्टिन पीटर्स

14
import os
print os.path.basename(__file__)

यह हमें केवल फ़ाइल नाम देगा। यदि फ़ाइल का एब्सपैथ c: \ abcd \ abc.py होता है, तो 2nd लाइन abc.py प्रिंट करेगा


14

यह पूरी तरह से स्पष्ट नहीं है कि आपके पास "फ़ाइल का फ़ाइलपथ जो वर्तमान में प्रक्रिया के भीतर चल रहा है" से है। sys.argv[0]आमतौर पर स्क्रिप्ट का स्थान होता है जिसे पायथन दुभाषिया द्वारा लागू किया गया था। Sys प्रलेखन की जाँच करेंअधिक विवरण के लिए ।

जैसा कि @Tim और @Pat Notz ने बताया है, __file__ विशेषता तक पहुँच प्रदान करती है

फ़ाइल जिसमें से मॉड्यूल लोड किया गया था, अगर यह एक फ़ाइल से लोड किया गया था


1
"os.path.abspath ( फाइल ) प्रिंट करें" और "प्रिंट इंस्पेक्ट.गेटफाइल (इंस्पेक्ट.काउंटरफ्रेम ())" जब हम अजगर प्रोग्राम को एक win32 exe पास करते हैं, तब काम नहीं करता है। केवल sys.argv [0] काम करता है! :) लेकिन आपको केवल नाम मिलता है!
एएफ।

11

मेरे पास एक स्क्रिप्ट है जो खिड़कियों के वातावरण में काम करती है। यह कोड छीन लिया गया है जिसे मैंने पूरा कर लिया है:

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

यह काफी हकी निर्णय है। लेकिन इसके लिए किसी बाहरी पुस्तकालय की आवश्यकता नहीं है और यह मेरे मामले में सबसे महत्वपूर्ण बात है।


1
मुझे इसके लिए "एसईएस, एसआईएस" आयात करना पड़ा, लेकिन अब तक यह सबसे अच्छा जवाब है जो वास्तव में स्ट्रिंग के अंत में फ़ाइल नाम के बिना सिर्फ पथ देता है।
इमामग्रस


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

निरीक्षण या किसी अन्य पुस्तकालय के लिए कोई ज़रूरत नहीं है।

यह मेरे लिए तब काम आया जब मुझे एक स्क्रिप्ट आयात करना पड़ा (एक अलग निर्देशिका से फिर निष्पादित स्क्रिप्ट), जिसने उसी स्क्रिप्ट में आयातित स्क्रिप्ट के रूप में रहने वाली कॉन्फ़िगरेशन फ़ाइल का उपयोग किया।


यह वांछित उत्तर का उत्पादन नहीं करेगा यदि वर्तमान कार्य निर्देशिका (os.getcwd) उस निर्देशिका से अलग है जिसमें फ़ाइल स्थित है।
आयरन तकिया

2
ऐसा कैसे? इस मामले में मेरे लिए ठीक काम करता है। मुझे वह निर्देशिका मिलती है जो फ़ाइल में स्थित होती है।
माइकल मिओर

@IronPillow शायद इस जवाब से आपको मदद मिलेगी। stackoverflow.com/a/41546830/3123191
Kwuite


6
import sys

print sys.path[0]

यह वर्तमान में निष्पादित स्क्रिप्ट का पथ मुद्रित करेगा


2
sys.path [0] बहुत उपयोगी है, लेकिन स्क्रिप्ट 1 का रास्ता देता है, स्क्रिप्ट 3 को अनुरोध के रूप में नहीं
जेम्स

कम से कम ओएस एक्स पर, 2.7 के साथ, मुझे नहीं लगता कि यह कुछ भी विश्वसनीय है। यह काम करता है अगर सीधे एक ही फाइल को निष्पादित करता है। जवाब से काम नहीं करता है, विशेष रूप से एक आयातित अंडे से
uchuugaka

5

मुझे लगता है कि यह सिर्फ __file__ लगता है जैसे आप निरीक्षण मॉड्यूल की जांच करना चाहते हैं ।


आह्ह्ह… अंजाम बहुत मुश्किल है। निरीक्षण मॉड्यूल का उपयोग करने के बारे में मेरी अन्य पोस्ट देखें।
पैट नोट्ज़

4

आप उपयोग कर सकते हैं 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'

4

चूंकि पायथन 3 काफी मुख्यधारा है, इसलिए मैं एक pathlibउत्तर को शामिल करना चाहता था , जैसा कि मेरा मानना ​​है कि यह अब फ़ाइल और पथ जानकारी तक पहुंचने का एक बेहतर साधन है।

from pathlib import Path

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

आप वर्तमान फ़ाइल की निर्देशिका की मांग कर रहे हैं, यह आसान के रूप में जोड़ने के रूप में है .parentके Path()बयान:

current_path: Path = Path(__file__).parent.resolve()

3
import sys
print sys.argv[0]

10
दुर्भाग्य से यह केवल तभी काम करता है यदि स्क्रिप्ट को इसके पूर्ण पथ के साथ बुलाया गया था, क्योंकि यह केवल कमांड लाइन पर "पहला तर्क" लौटाता है, जो स्क्रिप्ट को कॉलिंग है।
cregox

2

यह काम करना चाहिए:

import os,sys
filename=os.path.basename(os.path.realpath(sys.argv[0]))
dirname=os.path.dirname(os.path.realpath(sys.argv[0]))

2
print(__file__)
print(__import__("pathlib").Path(__file__).parent)

4
कोड केवल उत्तर हतोत्साहित करते हैं। कृपया कुछ स्पष्टीकरण जोड़ें कि यह समस्या को कैसे हल करता है, या यह मौजूदा उत्तरों से कैसे भिन्न है। समीक्षा से
निक

1

स्क्रिप्ट निष्पादित करने की निर्देशिका प्राप्त करने के लिए

 print os.path.dirname( inspect.getfile(inspect.currentframe()))

1

मैंने हमेशा वर्तमान कार्य निर्देशिका या CWD की ओएस सुविधा का उपयोग किया है। यह मानक पुस्तकालय का हिस्सा है, और इसे लागू करना बहुत आसान है। यहाँ एक उदाहरण है:

    import os
    base_directory = os.getcwd()

1
क्या आप अपना उत्तर संशोधित कर सकते हैं ताकि यह प्रश्न किए गए प्रश्न पर लागू हो? यह उत्तर इस सवाल पर लागू नहीं होता है "मुझे उस फ़ाइल का पथ और नाम कैसे मिलता है जो वर्तमान में निष्पादित हो रही है? "
Marco

1
यह वह मार्ग देता है जहाँ से आपने अजगर कमांड को चलाया था। तो यह तब काम करता है जब आप python script.pyउसी फ़ोल्डर में कमांड चलाते हैं जो आप पहले से ही हैं, जब वास्तव में यह pwdलिनक्स पर चलने के समान है ।
जॉर्ज

0

मैंने __file__ के साथ दृष्टिकोण का उपयोग किया है,
os.path.abspath(__file__)
लेकिन थोड़ी सी चाल है, यह .py फ़ाइल लौटाता है जब कोड पहली बार चलाया जाता है, अगले रन * .pyc फ़ाइल का नाम देते हैं
इसलिए मैं उसके साथ रहा:
inspect.getfile(inspect.currentframe())
या
sys._getframe().f_code.co_filename


0

मैंने एक फ़ंक्शन लिखा था जो ग्रहण डिबगर और यूनिटेस्ट को ध्यान में रखता है । यह आपके द्वारा लॉन्च की गई पहली स्क्रिप्ट का फ़ोल्डर लौटाता है। आप वैकल्पिक रूप से __file__ var निर्दिष्ट कर सकते हैं , लेकिन मुख्य बात यह है कि आपको इस चर को अपने सभी कॉलिंग पदानुक्रम में साझा नहीं करना है

हो सकता है कि आप अन्य मामलों को देख सकें जिन्हें मैंने नहीं देखा था, लेकिन मेरे लिए यह ठीक है।

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_))

0

प्लेटफ़ॉर्म (macOS / Windows / Linux) पर माइग्रेशन संगतता रखने के लिए, प्रयास करें:

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


2
ये गलत है। यह आपको वर्तमान पथ मिलता है, लेकिन वर्तमान फ़ाइल का पथ नहीं।
चार्ल्स प्लेजर

0

सबसे सरल तरीका है:

में script_1.py:

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

में script_2.py:

sys.argv[0]

पुनश्च: मैंने कोशिश की है execfile, लेकिन जब से यह एक स्ट्रिंग के रूप में script_2.py पढ़ता है, sys.argv[0]वापस आ गया <string>


0

यहाँ मैं क्या उपयोग करता हूँ इसलिए मैं बिना मुद्दे के अपना कोड कहीं भी फेंक सकता हूँ। __name__हमेशा परिभाषित किया जाता है, लेकिन __file__केवल तब परिभाषित किया जाता है जब कोड एक फ़ाइल के रूप में चलाया जाता है (जैसे कि IDLE / iPython में नहीं)।

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

वैकल्पिक रूप से, इसे इस प्रकार लिखा जा सकता है:

self_name = globals().get('__file__', locals().get('__file__', __name__))

-2

इनमें से अधिकांश उत्तर पायथन संस्करण 2.x या उससे पहले लिखे गए थे। पायथन 3.x में प्रिंट फ़ंक्शन के लिए सिंटैक्स कोष्ठक, यानी प्रिंट () की आवश्यकता के लिए बदल गया है।

तो, Python 2.x में user13993 से यह पहले वाला उच्च स्कोर उत्तर:

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

अजगर 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

-3

अगर आप बिना सिर्फ फ़ाइल नाम चाहते हैं ./या .pyआप यह कोशिश कर सकते हैं

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

file_name आपके द्वारा इंडेक्स को बदलकर आप जो चाहें उत्पन्न कर सकते हैं।


-3
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)

7
os.getcwd () PROCESS की वर्तमान कार्यशील निर्देशिका को लौटाता है, न कि वर्तमान में निष्पादित फ़ाइल की निर्देशिका। यह सही परिणाम वापस करने के लिए प्रकट हो सकता है, लेकिन ऐसे बहुत सारे मामले हैं जहां परिणाम वर्तमान फ़ाइल की मूल निर्देशिका नहीं होगी। ऊपर सुझाए अनुसार os.path.dirname ( फ़ाइल ) का उपयोग करना बेहतर है ।
समसपिन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.