python - لغة - منتديات بايثون




كيف يمكنني الحصول على مسار واسم الملف الذي يتم تنفيذه حاليا؟ (15)

لدي برامج نصية استدعاء ملفات البرامج النصية الأخرى ولكن أحتاج إلى الحصول على filepath للملف قيد التشغيل حالياً ضمن العملية.

على سبيل المثال ، لنفترض أن لدي ثلاثة ملفات. باستخدام execfile :

  • script_1.py يستدعي script_2.py .
  • بدوره ، يستدعي script_3.py .

كيف يمكنني الحصول على اسم الملف ومسار script_3.py ، من الرمز داخل script_3.py ، دون الحاجة إلى تمرير هذه المعلومات script_2.py من script_2.py ؟

(يؤدي تنفيذ os.getcwd() إلى filepath الخاص ببرنامج البداية الأصلي وليس الملف الحالي.)


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

أعتقد أن هذا أكثر نظافة:

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

ويحصل على نفس المعلومات مثل:

print inspect.getfile(inspect.currentframe())

حيث يكون [0] هو الإطار الحالي في المكدس (أعلى الكدسة) و [1] لاسم الملف ، قم بزيادة للرجوع للخلف في المكدس أي

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

سيكون اسم ملف البرنامج النصي الذي يسمى الإطار الحالي. أيضًا ، سيؤدي استخدام [-1] إلى الوصول إلى الجزء السفلي من المكدس ، وهو البرنامج النصي الأصلي للمكالمة.


إليك تجربة تستند إلى الإجابات في هذا الموضوع - مع Python 2.7.10 على Windows.

تلك القائمة على المكدس هي الوحيدة التي تعطي نتائج موثوقة. الأخيرين لديهم أقصر بناء ، أي

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

وهنا لهذه تضاف إلى تميز الكلية كما وظائف! الفضل فيUsagi و @ pablog

استنادا إلى الملفات الثلاثة التالية ، وتشغيل script1.py من مجلدها مع python script1.py (كما حاول execfiles مع المسارات المطلقة والاستدعاء من مجلد منفصل).

C: \ testpath \ script1.py: execfile('script2.py')
C: \ testpath \ script2.py: execfile('lib/script3.py')
C: \ testpath \ ليب \ 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

استخدمت النهج مع __file__
os.path.abspath(__file__)
ولكن هناك خدعة صغيرة ، تقوم بإرجاع الملف .py عند تشغيل الكود في المرة الأولى ، فيظهر تشغيل التالي اسم * .pyc
لذلك بقيت مع:
inspect.getfile(inspect.currentframe())
أو
sys._getframe().f_code.co_filename



تكون الاقتراحات التي تم وضع علامة عليها كأفضل صحيحة إذا كان النص البرمجي يتكون من ملف واحد فقط.

إذا كنت تريد معرفة اسم الملف التنفيذي (أي تمرير ملف الجذر إلى مترجم python للبرنامج الحالي) من ملف قد يتم استيراده كوحدة نمطية ، فستحتاج إلى القيام بذلك (دعنا نفترض أن هذا في ملف المسمى 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]

لدي برنامج نصي يجب أن يعمل تحت بيئة النوافذ. هذا الرمز الذي تم قصه هو ما انتهيت منه:

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

انه قرار سخيف لكنه لا يتطلب أي مكتبات خارجية وهو أهم شيء في حالتي.


للحصول على دليل تنفيذ البرنامج النصي

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

ليس من الواضح تمامًا ما الذي تعنيه بـ "مسار الملف الذي يتم تشغيله حاليًا ضمن العملية". عادةً ما يحتوي sys.argv[0] على موقع البرنامج النصي الذي تم استدعاؤه بواسطة مترجم Python. راجع وثائق sys لمزيد من التفاصيل.

كما أشارTim و @ Pat Notz ، فإن خاصية __file__ توفر الوصول إلى

الملف الذي تم تحميل الوحدة منه ، إذا تم تحميله من ملف


يجب أن يعمل هذا:

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

__file__

كما قال الآخرون. قد ترغب أيضًا في استخدام os.path.realpath الرمزية:

import os

os.path.realpath(__file__)

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)

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

لا حاجة لفحص أو أي مكتبة أخرى.

لقد عمل هذا لي عندما اضطررت إلى استيراد برنامج نصي (من دليل مختلف ثم البرنامج النصي الذي تم تنفيذه) ، والذي استخدم ملف تكوين موجودًا في نفس المجلد مثل النص المستورد.


import os
print os.path.basename(__file__)

هذا سيعطينا اسم الملف فقط. بمعنى ، إذا كان ملف abspath هو c: \ abcd \ abc.py ، فسيتم طباعة السطر الثاني abc.py


import sys
print sys.argv[0]




file