पायथन में वर्तमान स्क्रिप्ट का नाम प्राप्त करें


407

मैं पायथन स्क्रिप्ट का नाम लेने की कोशिश कर रहा हूं जो वर्तमान में चल रही है।

मेरे पास एक स्क्रिप्ट है जिसे foo.pyमैं स्क्रिप्ट नाम प्राप्त करने के लिए कुछ इस तरह करना चाहता हूं:

print Scriptname

जवाबों:


620

आप __file__वर्तमान फ़ाइल का नाम प्राप्त करने के लिए उपयोग कर सकते हैं । जब मुख्य मॉड्यूल में उपयोग किया जाता है, तो यह उस स्क्रिप्ट का नाम है जिसे मूल रूप से लागू किया गया था।

यदि आप निर्देशिका भाग को छोड़ना चाहते हैं (जो मौजूद हो सकता है), तो आप उपयोग कर सकते हैं os.path.basename(__file__)


15
पायथन 3.2: " Exception NameError: NameError("global name '__file__' is not defined",)"
सदाऊ

20
@ सादाऊ: __file__इंटरैक्टिव दुभाषिया में परिभाषित नहीं है, क्योंकि यह वहां अर्थहीन है। यह आयात कार्यान्वयन द्वारा निर्धारित किया जाता है, इसलिए यदि आप एक गैर-मानक आयात तंत्र का उपयोग करते हैं तो यह भी परेशान हो सकता है।
स्वेन मार्नाच

8
कम से कम पायथन 2.7 के लिए, मेरा मानना ​​है कि import osइसके लिए काम करना आवश्यक है। मैं इस जवाब में जोड़ देंगे।
निक चामास

14
@ cdunn2001: import osऔर import os.pathपूरी तरह से समकक्ष हैं।
स्वेन मार्नाच

2
@ sven-marnach: ओह, तुम सही हो । मैं वर्षों से यह गलत कर रहा हूँ!
cdunn2001

136
import sys
print sys.argv[0]

यह प्रिंट होगा foo.pyके लिए python foo.py, dir/foo.pyके लिए python dir/foo.pyआदि, यह करने के लिए पहला तर्क है python। (ध्यान दें कि py2.exe के बाद यह होगा foo.exe।)


33
@DenisMalinovsky: परिभाषित करें "काम नहीं करेगा"। यदि आप कहते हैं python linkfile.py, जहां linkfile.pyएक सिम्लिंक है realfile.py, sys.argv[0]वह होगा 'linkfile.py', जो आप चाहते हैं या नहीं हो सकता है; यह निश्चित रूप से मैं क्या उम्मीद है__file__वही है: यह होगा linkfile.py। आप जानना चाहते हैं तो 'realfile.py'से 'linkfile.py', कोशिश os.path.realpath('linkfile.py')
क्रिस मॉर्गन

6
+1 क्योंकि यह (ए) थोड़ा नट और (बी) अभी भी मॉड्यूल में काम करेगा (जहां फ़ाइल चर मॉड्यूल फ़ाइल होगी, निष्पादित नहीं होगी)।
रोबर्ट

यह उत्तर अच्छा है क्योंकि यह आईडीएलई में भी काम करता है। एक नोट के रूप में, सिर्फ फ़ाइल नाम पाने के लिए, आप os.path.basename (sys.argv [0])
स्टीवन ब्लूएन

इससे भी महत्वपूर्ण बात, यह मुख्य फ़ाइल के अंदर से काम नहीं करता है। इस का उपयोग न करें, __file__इसके बजाय का उपयोग करें ।
अपोलिस

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

70

पूर्णता के लिए, मैंने सोचा कि यह विभिन्न संभावित परिणामों को संक्षेप में प्रस्तुत करना और प्रत्येक के सटीक व्यवहार के लिए संदर्भों की आपूर्ति करना सार्थक होगा:

  • __file__वर्तमान में निष्पादित फ़ाइल है, जैसा कि आधिकारिक दस्तावेज में विस्तृत है :

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

    पाइथन 3.4 से, प्रति अंक 18416 से , __file__हमेशा एक निरपेक्ष पथ होता है, जब तक कि वर्तमान में निष्पादित फ़ाइल एक स्क्रिप्ट है जिसे सीधे निष्पादित किया गया है ( -mकमांड लाइन विकल्प के साथ दुभाषिया के माध्यम से नहीं ) एक रिश्तेदार पथ का उपयोग करके।

  • __main__.__file__(आयात करने की आवश्यकता होती है __main__) बस मुख्य मॉड्यूल के पूर्वोक्त __file__विशेषता तक पहुँचता है , उदाहरण के लिए स्क्रिप्ट जो कमांड लाइन से लगाई गई थी।

  • sys.argv[0](आयात की आवश्यकता है sys) स्क्रिप्ट नाम है जिसे कमांड लाइन से लागू किया गया था, और आधिकारिक दस्तावेज में विस्तृत रूप से एक पूर्ण मार्ग हो सकता है :

    argv[0]स्क्रिप्ट नाम है (यह ऑपरेटिंग सिस्टम निर्भर करता है कि यह एक पूर्ण पथनाम है या नहीं)। यदि कमांड -cदुभाषिया के लिए कमांड लाइन विकल्प का उपयोग करके निष्पादित किया गया था , argv[0]तो स्ट्रिंग पर सेट किया गया है '-c'। यदि पायथन इंटरप्रेटर के लिए कोई स्क्रिप्ट नाम नहीं दिया गया था, argv[0]तो रिक्त स्ट्रिंग है।

    के रूप में में उल्लेख किया है इस सवाल का एक और उत्तर , अजगर स्क्रिप्ट है कि इस तरह के रूप में उपकरण के माध्यम से स्टैंड-अलोन निष्पादन योग्य कार्यक्रमों में बदल दिया गया py2exe या PyInstaller वांछित परिणाम प्रदर्शित नहीं हो सकता है जब इस दृष्टिकोण का उपयोग कर (यानी sys.argv[0]नाम के बजाय निष्पादन के नाम का आयोजन होगा उस निष्पादन योग्य के भीतर मुख्य पायथन फ़ाइल)।

  • यदि उपरोक्त विकल्पों में से कोई भी काम नहीं करता है, तो शायद अनियमित आयात ऑपरेशन के कारण, निरीक्षण मॉड्यूल उपयोगी साबित हो सकता है। विशेष रूप से, लागू inspect.getfile(...)पर inspect.currentframe(), काम कर सकता था हालांकि बाद होगा लौटनेNone जब बिना एक कार्यान्वयन में चल अजगर ढेर फ्रेम।


प्रतीकात्मक लिंक को संभालना

यदि वर्तमान स्क्रिप्ट एक प्रतीकात्मक लिंक है, तो उपरोक्त सभी वास्तविक फ़ाइल के पथ के बजाय प्रतीकात्मक लिंक का मार्ग लौटाएंगे और os.path.realpath(...)बाद में निकालने के लिए इसे लागू किया जाना चाहिए।


इसके अलावा जोड़तोड़ जो वास्तविक फ़ाइल नाम को निकालते हैं

os.path.basename(...)वास्तविक फ़ाइल नाम निकालने के लिए उपरोक्त में से किसी पर भी लागू किया जा सकता है और os.path.splitext(...)इसके प्रत्यय को कम करने के लिए वास्तविक फ़ाइल नाम पर लागू किया जा सकता है, जैसे किos.path.splitext(os.path.basename(...))

से अजगर 3.4 के बाद से, प्रति पीईपी 428 , PurePathवर्ग के pathlibमॉड्यूल उपरोक्त में से किसी पर अच्छी तरह से रूप में इस्तेमाल किया जा सकता है। विशेष रूप से, pathlib.PurePath(...).nameवास्तविक फ़ाइल नाम को pathlib.PurePath(...).stemनिकालता है और वास्तविक फ़ाइल नाम को उसके प्रत्यय के बिना निकालता है।


66

ध्यान दें कि __file__वह फाइल देगा जहां यह कोड रहता है, जिसे आयात किया जा सकता है और मुख्य फाइल से अलग किया जा सकता है। मुख्य फ़ाइल प्राप्त करने के लिए, विशेष __main__ मॉड्यूल का उपयोग किया जा सकता है:

import __main__ as main
print(main.__file__)

ध्यान दें कि __main__.__file__पायथन 2.7 में काम करता है, लेकिन 3.2 में नहीं, इसलिए इसे पोर्टेबल बनाने के लिए आयात-ऊपर सिंटैक्स का उपयोग करें।


यह कई मामलों में काम करता है लेकिन तब नहीं जब मैं भाषा rPythonसे पैकेज का उपयोग कर रहा हूं R। यह एक असाधारण मामला होना चाहिए जिसे संभालना बहुत मुश्किल है।
लियोनिद

दरअसल, rPython पैकेज अजगर इंटरप्रेटर को एम्बेड करता है, जिसका अर्थ है कि कोई 'मुख्य' फाइल नहीं है, जब अजगर अपने आप चल रहा होता है (आपको कभी भी ऐसा ही व्यवहार मिलेगा जब अजगर एम्बेडेड है)। यह __main__आंतरिक रूप से आयात करता है , Rऔर इसके बीच चर चर में उपयोग के लिए python, इसलिए इसे __main__.__file__और कुछ भी कॉल करने से पहले सेट करना अपेक्षाकृत आसान होगा , लेकिन मुझे यह भी निश्चित नहीं है कि इस मामले में एक उचित मूल्य क्या होगा।
पर्किन्स

42

उपरोक्त उत्तर अच्छे हैं। लेकिन मैंने इस विधि को उपरोक्त परिणामों का उपयोग करके अधिक कुशल पाया।
यह वास्तविक स्क्रिप्ट फ़ाइल नाम के परिणामस्वरूप एक पथ नहीं है।

import sys    
import os    
file_name =  os.path.basename(sys.argv[0])

1
मुझे एक्सटेंशन को भी विभाजित करना पसंद है, इसलिए मैं उपयोग करता हूं: os.path.splitext (os.path.basename (sys.argv [0])) [0]
RufusVS

19

आधुनिक पायथन संस्करणों (3.4+) के लिए, Path(__file__).nameअधिक मुहावरेदार होना चाहिए। इसके अलावा, Path(__file__).stemआप .pyविस्तार के बिना स्क्रिप्ट नाम देता है ।


NameError: नाम 'Path' परिभाषित नहीं है
RufusVS

5
आपको from pathlib import Pathपहले होना चाहिए ।
एमिल मेलनिकोव

"आधुनिक" का अर्थ है पायथन 3.x?
ईनपोकलम

1
@einpoklum pathlibको Python 3.4 में पेश किया गया था, इसलिए इसे Python 3.4 से शुरू करना चाहिए।
एंड्री सेमकिन


9

नोट: यदि आप पायथन 3+ का उपयोग कर रहे हैं, तो आपको इसके बजाय प्रिंट () फ़ंक्शन का उपयोग करना चाहिए

यह मानते हुए कि फ़ाइल नाम foo.pyनीचे का स्निपेट है

import sys
print sys.argv[0][:-3]

या

import sys
print sys.argv[0][::-1][3:][::-1]

अधिक पात्रों के साथ अन्य सीमाओं के लिए, उदाहरण के लिए फ़ाइल नाम foo.pypy

import sys
print sys.argv[0].split('.')[0]

अगर तुम एक निरपेक्ष मार्ग से निकलना चाहते हो

import sys
print sys.argv[0].split('/')[-1].split('.')[0]

उत्पादन होगा foo


1
sys.argv [0] [: - 3] करना होगा
kon psych

@konpsych वह अधिक सुंदर है
xtonousou

दोनों के बीच बड़ा अंतर है __file__और sys.argv[0]देखें, stackoverflow.com/questions/5851588/…
मैक्सिकन गेनेंको

8

Sys में पहला तर्क वर्तमान फ़ाइल नाम होगा इसलिए यह काम करेगा

   import sys
   print sys.argv[0] # will print the file name

7

यदि आप एक असामान्य आयात कर रहे हैं (उदाहरण के लिए, यह एक विकल्प फ़ाइल है), कोशिश करें:

import inspect
print (inspect.getfile(inspect.currentframe()))

ध्यान दें कि यह फ़ाइल में पूर्ण पथ लौटाएगा।


3

हम बिना विस्तार के वर्तमान स्क्रिप्ट नाम प्राप्त करने के लिए यह कोशिश कर सकते हैं।

import os

script_name = os.path.splitext(os.path.basename(__file__))[0]

2

चूंकि ओपी ने वर्तमान स्क्रिप्ट फ़ाइल के नाम के लिए कहा, मैं पसंद करूंगा

import os
os.path.split(sys.argv[0])[1]



0

यह सभी उत्तर महान हैं, लेकिन कुछ समस्याएं हैं जिन्हें आप पहली नज़र में नहीं देख सकते हैं।

हम जो चाहते हैं उसे परिभाषित करते हैं - हम उस स्क्रिप्ट का नाम चाहते हैं जिसे निष्पादित किया गया था, वर्तमान मॉड्यूल का नाम नहीं है - इसलिए __file__केवल तभी काम करेगा जब इसे निष्पादित स्क्रिप्ट में उपयोग किया जाता है, न कि किसी आयातित मॉड्यूल में। sys.argvयह भी संदिग्ध है - क्या होगा यदि आपका कार्यक्रम पाइस्टेस्ट द्वारा बुलाया गया था? या pydoc धावक? या अगर यह uwsgi द्वारा बुलाया गया था?

और - स्क्रिप्ट नाम प्राप्त करने की एक तीसरी विधि है, मैंने उत्तर में देखा है - आप स्टैक का निरीक्षण कर सकते हैं।

एक और समस्या यह है, कि आप (या कुछ अन्य कार्यक्रम) के साथ छेड़छाड़ कर सकते हैं sys.argvऔर __main__.__file__- यह मौजूद हो सकता है, यह नहीं हो सकता है। यह मान्य हो सकता है, या नहीं। यदि स्क्रिप्ट (वांछित परिणाम) मौजूद है तो कम से कम आप देख सकते हैं!

मेरी लाइब्रेरी बिट्रॉक्स / lib_programname github पर ठीक यही करती है:

  • अगर __main__मौजूद है तो जाँच करें
  • अगर __main__.__file__मौजूद है तो जाँच करें
  • देता है __main__.__file__एक वैध परिणाम (है कि स्क्रिप्ट मौजूद है?)
  • यदि नहीं: sys.argv की जाँच करें:
  • वहाँ pysest, docrunner, आदि sys.argv में है? -> यदि हाँ, तो उस पर ध्यान न दें
  • क्या हम यहां एक वैध परिणाम प्राप्त कर सकते हैं?
  • यदि नहीं: स्टैक का निरीक्षण करें और संभवतः वहां से परिणाम प्राप्त करें
  • यदि स्टैक एक वैध परिणाम नहीं देता है, तो एक अपवाद फेंकें।

इस तरह से, मेरे समाधान अब तक के साथ काम कर रहा है setup.py test, uwsgi, pytest, pycharm pytest, pycharm docrunner (doctest), dreampie,eclipse

Dough Hellman की उस समस्या के बारे में एक अच्छा ब्लॉग लेख भी है, "पायथन से एक प्रक्रिया का नाम निर्धारित करना"


0

अजगर 3.5 के रूप में आप बस कर सकते हैं:

from pathlib import Path
Path(__file__).stem

यहाँ और देखें: https://docs.python.org/3.5/library/pathlib.html#pathlib.PurePath.stem

उदाहरण के लिए, मेरे पास test.pyइसके अंदर नामित मेरी उपयोगकर्ता निर्देशिका के तहत एक फ़ाइल है:

from pathlib import Path

print(Path(__file__).stem)
print(__file__)

इस आउटपुट को चलाना:

>>> python3.6 test.py
test
test.py
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.