[python] كيف تتحقق من وجود ملف؟


Answers

لديك وظيفة os.path.exists :

import os.path
os.path.exists(file_path)

يؤدي هذا إلى إرجاع True لكل من الملفات والدلائل ، ولكن يمكنك بدلاً من ذلك استخدام os.path.isfile لاختبار ما إذا كان الملف محددًا أم لا. يتبع symlinks.

Question

كيف ترى ما إذا كان الملف موجودًا أم لا ، دون استخدام بيان try ؟




لا يبدو أن هناك اختلافًا وظيفيًا ذا معنى بين المحاولة / isfile() و isfile() ، لذلك يجب عليك استخدام أي منها منطقي.

إذا كنت ترغب في قراءة ملف ، إذا كان موجودًا ، فافعل ذلك

try:
    f = open(filepath)
except IOError:
    print 'Oh dear.'

ولكن إذا أردت فقط إعادة تسمية ملف إذا كان موجودًا ، وبالتالي لا تحتاج إلى فتحه ، فافعل ذلك

if os.path.isfile(filepath):
    os.rename(filepath, filepath + '.old')

إذا كنت تريد الكتابة إلى ملف ، إذا لم يكن موجودًا ، فافعل ذلك

# python 2
if not os.path.isfile(filepath):
    f = open(filepath, 'w')

# python 3, x opens for exclusive creation, failing if the file already exists
try:
    f = open(filepath, 'wx')
except IOError:
    print 'file already exists'

إذا كنت بحاجة إلى تأمين الملفات ، فهذه مسألة مختلفة.




import os
os.path.exists(path) # returns whether the path (dir or file) exists or not
os.path.isfile(path) # returns whether the file exists or not



Here's a 1 line Python command for the Linux command line environment. I find this VERY HANDY since I'm not such a hot Bash guy.

python -c "import os.path; print os.path.isfile('/path_to/file.xxx')"

I hope this is helpful.




if os.path.isfile(path_to_file):
    try: 
        open(path_to_file)
            pass
    except IOError as e:
        print "Unable to open file"

Raising exceptions is considered to be an acceptable, and Pythonic, approach for flow control in your program. Consider handling missing files with IOErrors. In this situation, an IOError exception will be raised if the file exists but the user does not have read permissions.

SRC: http://www.pfinn.net/python-check-if-file-exists.html




يمكنك تجربة هذا (أكثر أمانًا):

try:
    # http://effbot.org/zone/python-with-statement.htm
    # 'with' is safer to open a file
    with open('whatever.txt') as fh:
        # Do something with 'fh'
except IOError as e:
    print("({})".format(e))

سيكون ouput:

([Errno 2] لا يوجد ملف أو دليل مثل: "whatever.txt")

ثم ، اعتمادا على النتيجة ، يمكن للبرنامج الخاص بك أن يستمر في العمل من هناك أو يمكنك التعليمة البرمجية لإيقافه إذا كنت تريد.




import os
#Your path here e.g. "C:\Program Files\text.txt"
#For access purposes: "C:\\Program Files\\text.txt"
if os.path.exists("C:\..."):   
    print "File found!"
else:
    print "File not found!"

يسهل os الاستيراد من التنقل وإجراء الإجراءات القياسية مع نظام التشغيل الخاص بك.

للرجوع اليها انظر أيضا share

إذا كنت بحاجة إلى عمليات عالية المستوى ، shutil




I'm the author of a package that's been around for about 10 years, and it has a function that addresses this question directly. Basically, if you are on a non-Windows system, it uses Popen to access find . However, if you are on Windows, it replicates find with an efficient filesystem walker.

The code itself does not use a try block… except in determining the operating system and thus steering you to the "Unix"-style find or the hand-buillt find . Timing tests showed that the try was faster in determining the OS, so I did use one there (but nowhere else).

>>> import pox
>>> pox.find('*python*', type='file', root=pox.homedir(), recurse=False)
['/Users/mmckerns/.python']

And the doc…

>>> print pox.find.__doc__
find(patterns[,root,recurse,type]); Get path to a file or directory

    patterns: name or partial name string of items to search for
    root: path string of top-level directory to search
    recurse: if True, recurse down from root directory
    type: item filter; one of {None, file, dir, link, socket, block, char}
    verbose: if True, be a little verbose about the search

    On some OS, recursion can be specified by recursion depth (an integer).
    patterns can be specified with basic pattern matching. Additionally,
    multiple patterns can be specified by splitting patterns with a ';'
    For example:
        >>> find('pox*', root='..')
        ['/Users/foo/pox/pox', '/Users/foo/pox/scripts/pox_launcher.py']

        >>> find('*shutils*;*init*')
        ['/Users/foo/pox/pox/shutils.py', '/Users/foo/pox/pox/__init__.py']

>>>

The implementation, if you care to look, is here: https://github.com/uqfoundation/pox/blob/89f90fb308f285ca7a62eabe2c38acb87e89dad9/pox/shutils.py#L190




2017/12/22 :

على الرغم من أنه تم إدراج كل طريقة ممكنة تقريبًا في (على الأقل واحدة من) الإجابات الموجودة (على سبيل المثال Python 3.4 تم إضافة أشياء معينة) ، سأحاول تجميع كل شيء معًا.

ملاحظة : كل ​​جزء من رمز مكتبة Python القياسي الذي سأقوم بنشره ، ينتمي إلى الإصدار 3.5.3 (تكون doc quotes خاصة بالإصدار 3 ).

بيان المشكلة :

  1. تحقق من الملف ( arguable : also folder ("special" file)؟) being
  2. لا تستخدم try / except / else / في finally كتل

الحلول الممكنة :

  1. [بيثون]: os.path. موجود ( المسار ) (تحقق أيضا من أفراد الأسرة وظيفة أخرى مثل os.path.isfile ، os.path.isdir ، os.path.lexists مختلفة قليلا)

    os.path.exists(path)
    

    إرجاع True إذا كان المسار يشير إلى مسار موجود أو واصف ملف مفتوح. إرجاع False لروابط رمزية مقطوعة. على بعض الأنظمة الأساسية ، قد ترجع هذه الدالة False إذا لم يتم منح الإذن لتنفيذ os.stat() على الملف المطلوب ، حتى إذا كان المسار موجودًا فعليًا.

    كل شيء جيد ، ولكن في حالة اتباع شجرة الاستيراد:

    • os.path - posixpath.py ( ntpath.py )

      • genericpath.py ، سطر ~ # 20 +

        def exists(path):
            """Test whether a path exists.  Returns False for broken symbolic links"""
            try:
                st = os.stat(path)
            except os.error:
                return False
            return True
        

    انها مجرد try/except كتلة حول os.stat() os.stat() . لذا ، فإن الرمز الخاص بك هو try/except مجانية ، ولكن أقل في framestack هناك (على الأقل) كتلة واحدة من هذا القبيل. هذا ينطبق أيضا على funcs أخرى ( بما في ذلك os.path.isfile ).

    1.1. [بايثون]: pathlib.Path. is_file ()

    • انها وسيلة مربي الحيوانات (وأكثر python جيم) للتعامل مع المسارات ، ولكن
    • تحت غطاء المحرك ، يفعل نفس الشيء بالضبط ( pathlib.py ، السطر ~ # 1330 ):

      def is_file(self):
          """
          Whether this path is a regular file (also True for symlinks pointing
          to regular files).
          """
          try:
              return S_ISREG(self.stat().st_mode)
          except OSError as e:
              if e.errno not in (ENOENT, ENOTDIR):
                  raise
              # Path doesn't exist or is a broken symlink
              # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
              return False
      
  2. [بايثون]: مع مدراء سياق البيان . إما:

    • اصنع واحدا:

      class Swallow:  # Dummy example
          swallowed_exceptions = (FileNotFoundError,)
      
          def __enter__(self):
              print("Entering...")
      
          def __exit__(self, exc_type, exc_value, exc_traceback):
              print("Exiting:", exc_type, exc_value, exc_traceback)
              return exc_type in Swallow.swallowed_exceptions  # only swallow FileNotFoundError (not e.g. TypeError - if the user passes a wrong argument like None or float or ...)
      
      • واستخدامها - سوف isfile سلوك isfile (لاحظ أن هذا هو فقط لأغراض التوضيح ، لا تحاول كتابة مثل هذا الرمز للإنتاج ):

        import os
        import stat
        
        
        def isfile_seaman(path):  # Dummy func
            result = False
            with Swallow():
                result = stat.S_ISREG(os.stat(path).st_mode)
            return result
        
    • استخدم [بايثون]: contextlib. منع ( * الاستثناءات ) - الذي تم تصميمه خصيصًا لقمع الاستثناءات بشكل انتقائي


    ولكن ، يبدو أنها أغلفة على try/except/else/finally كتل ، كما [بيثون]: بيان مع يقول:

    هذا يسمح try مشتركة ... except ... أنماط الاستخدام في finally لتكون مغلفة لإعادة الاستخدام مريحة.

  3. وظائف اجتياز نظام الملفات (والبحث في نتائج العنصر (العناصر) المطابقة)


    بما أن هذه التكرارات على مجلدات ، (في معظم الحالات) فهي غير فعالة لمشكلتنا (هناك استثناءات ، مثل غير blobarded glob bing - كما أشارShadowRanger) ، لذلك أنا لن أصر عليها. ناهيك عن أنه في بعض الحالات ، قد تكون معالجة اسم الملف مطلوبة.

  4. [بيثون]: السراج. access ( path، mode، *، dir_fd = None، effective_ids = False، follow_symlinks = True ) التي يكون سلوكها قريب من os.path.exists (في الواقع يكون أوسع ، ويرجع ذلك أساسًا إلى الوسيطة الثانية 2)

    • قد تؤدي أذونات المستخدم إلى تقييد الملف "مستوى الرؤية" كما تنص عليه الوثيقة:

      ... اختبار إذا كان لدى المستخدم الذي يحتفظ به حق الوصول المحدد إلى المسار . يجب أن يكون وضع F_OK لاختبار وجود مسار ...

    os.access("/tmp", os.F_OK)
    

    وبما أنني أعمل أيضًا في C ، أستخدم هذه الطريقة أيضًا لأنه تحت الغطاء ، تستدعي واجهة برمجة التطبيقات الأصلية (مرة أخرى ، عبر " $ {PYTHON_SRC_DIR} /Modules/posixmodule.c ") ، ولكنها تفتح أيضًا بوابة للمستخدم المحتمل أخطاء ، وليس كما بيثون جيم مثل المتغيرات الأخرى. لذلك ، كما أشارAaronHall بشكل صحيح ، لا تستخدمه إلا إذا كنت تعرف ما تفعله:

    ملاحظة : الاتصال بـ API الأصلي ممكن أيضًا عبر [Python]: ctypes - مكتبة وظائف أجنبية لـ Python ، ولكن في معظم الحالات يكون الأمر أكثر تعقيدًا.

    ( الفوز محددة): منذ تصدير msvcr * ( vcruntime * ) إلى [MSDN]: _access ، _wccess وظيفة الأسرة كذلك ، وهنا مثال على ذلك:

    Python 3.5.3 (v3.5.3:1880cb95a742, Jan 16 2017, 16:02:32) [MSC v.1900 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import os, ctypes
    >>> ctypes.CDLL("msvcrt")._waccess(u"C:\\Windows\\System32\\cmd.exe", os.F_OK)
    0
    >>> ctypes.CDLL("msvcrt")._waccess(u"C:\\Windows\\System32\\___cmd.exe", os.F_OK)
    -1
    

    ملاحظات :

    • على الرغم من أنها ليست ممارسة جيدة ، فأنا أستخدم os.F_OK في المكالمة ، ولكن هذا فقط من أجل الوضوح (قيمته هي 0 )
    • أستخدم _waccess بحيث يعمل الرمز نفسه على Python3 و Python2 (على الرغم من وجود اختلافات ذات صلة unicode بينهما)
    • على الرغم من أن هذا يستهدف منطقة محددة جدًا ، إلا أنه لم يتم ذكره في أي من الإجابات السابقة


    وينظف Lnx ( Ubtu (16 x64) ) أيضًا:

    Python 3.5.2 (default, Nov 17 2016, 17:05:23)
    [GCC 5.4.0 20160609] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import os, ctypes
    >>> ctypes.CDLL("/lib/x86_64-linux-gnu/libc.so.6").access(b"/tmp", os.F_OK)
    0
    >>> ctypes.CDLL("/lib/x86_64-linux-gnu/libc.so.6").access(b"/tmp1", os.F_OK)
    -1
    

    ملاحظات :

    • وبدلاً من ذلك ، فإن مسار libc ( "/lib/x86_64-linux-gnu/libc.so.6" ) قد يتغير (وعلى الأرجح ، سيختلف) عبر الأنظمة ، None يمكن تمرير None (أو السلسلة الفارغة) إلى مُنشئ CDLL ( ctypes.CDLL(None).access(b"/tmp", os.F_OK) ). وفقا ل [رجل]: DLOPEN (3) :

      إذا كان اسم الملف هو NULL ، فسيكون المقبض المرتجع للبرنامج الرئيسي. عند إعطاء dlsym () ، يتسبب هذا المقبض في البحث عن رمز في البرنامج الرئيسي ، متبوعًا بكافة الكائنات المشتركة التي تم تحميلها عند بدء تشغيل البرنامج ، ثم يتم تحميل كافة الكائنات المشتركة بواسطة dlopen () مع العلامة RTLD_GLOBAL .

      • يرتبط البرنامج الرئيسي (الحالي) ( python ) بمقابلة libc ، لذلك سيتم تحميل رموزه (بما في ذلك access )
      • يجب التعامل مع هذا الأمر بحذر ، حيث أن الوظائف مثل Py_Main و (جميع) الأخرى متاحة ؛ الاتصال بهم يمكن أن يكون له آثار كارثية (على البرنامج الحالي)
      • لا ينطبق هذا أيضًا على Win (ولكن هذا ليس مشكلة كبيرة ، حيث توجد msvcrt.dll في "٪ SystemRoot٪ \ System32" الموجود في ٪ PATH٪ بشكل افتراضي). كنت أرغب في اتخاذ أشياء أخرى وتكرار هذا السلوك على وين (وإرسال التصحيح) ، ولكن كما اتضح ، [MSDN]: وظيفة GetProcAddress فقط "ترى" رموز التصدير ، لذلك ما لم يعلن شخص ما الوظائف في الملف التنفيذي الرئيسي مثل __declspec(dllexport) (لماذا يفعل الشخص العادي على الأرض ذلك؟) ، البرنامج الرئيسي قابل للحمل ولكنه غير قابل للاستخدام إلى حد كبير
  5. قم بتركيب وحدة طرفية ثالثة مع إمكانيات نظام الملفات

    على الأرجح ، سوف تعتمد على واحدة من الطرق المذكورة أعلاه (ربما مع تخصيصات طفيفة).
    أحد الأمثلة سيكون (مرة أخرى ، وين معين) [GitHub]: Python for Windows (pywin32) Extensions ، وهو غلاف Python فوق WINAPI s.

    ولكن ، بما أن هذا أشبه بالحل ، فأنا أتوقف هنا.

  6. حل آخر (عرجاء) ( gainarie ) هو (كما أحب أن أسميها ،) النهج sysadmin : استخدام Python كمغلف لتنفيذ أوامر shell

    • الفوز :

      (py35x64_test) e:\Work\Dev\\q000082831>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os; print(os.system('dir /b \"C:\\Windows\\System32\\cmd.exe\" > nul 2>&1'))"
      0
      
      (py35x64_test) e:\Work\Dev\\q000082831>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os; print(os.system('dir /b \"C:\\Windows\\System32\\cmd.exe.notexist\" > nul 2>&1'))"
      1
      
    • Lnx ( Ubtu ):

      [cfati@cfati-ubtu16x64-0:~]> python3 -c "import os; print(os.system('ls \"/tmp\" > /dev/null 2>&1'))"
      0
      [cfati@cfati-ubtu16x64-0:~]> python3 -c "import os; print(os.system('ls \"/tmp.notexist\" > /dev/null 2>&1'))"
      512
      

الخلاصة :

  • يمكنك استخدام try / except / else / في finally ، لأنها يمكن أن تمنعك من الوقوع في سلسلة من المشاكل السيئة. مثال مضاد يمكن التفكير فيه ، هو الأداء: هذه الكتل باهظة التكلفة ، لذا حاول ألا تضعها في الكود الذي من المفترض تشغيله مئات آلاف المرات في الثانية (ولكن في معظم الحالات) ينطوي على الوصول إلى القرص ، لن يكون هذا هو الحال).

الملاحظة النهائية (الملاحظات) :

  • سأحاول الحفاظ على تحديثها ، أي اقتراحات هي موضع ترحيب ، وسوف أدمج أي شيء مفيد سيظهر في الإجابة



import os.path

if os.path.isfile(filepath):



import os
path = /path/to/dir

root,dirs,files = os.walk(path).next()
if myfile in files:
   print "yes it exists"

This is helpful when checking for several files. Or you want to do a set intersection/ subtraction with an existing list.




Python 3.4 + لديه وحدة مسار كائن المنحى: pathlib . باستخدام هذه الوحدة الجديدة ، يمكنك التحقق مما إذا كان الملف موجودًا على هذا النحو:

import pathlib
p = pathlib.Path('path/to/file')
if p.is_file():  # or p.is_dir() to see if it is a directory
    # do stuff

يمكنك (ويجب عادةً) استخدام try/except الحظر عند فتح الملفات:

try:
    with p.open() as f:
        # do awesome stuff
except OSError:
    print('Well darn.')

تحتوي وحدة pathlib على الكثير من الأشياء الرائعة الموجودة فيها: غلابة مريحة ، فحص مالك الملف ، سهولة الانضمام إلى المسار ، إلخ. الأمر يستحق التدقيق. إذا كنت تستخدم Python الأقدم (الإصدار 2.6 أو أحدث) ، فلا يزال بإمكانك تثبيت pathlib مع pip:

# installs pathlib2 on older Python versions
# the original third-party module, pathlib, is no longer maintained.
pip install pathlib2

ثم قم باستيرادها كما يلي:

# Older Python versions
import pathlib2 as pathlib



إذا كان الملف مفتوحًا ، فيمكنك استخدام أحد الأساليب التالية:

>>> with open('somefile', 'xt') as f: #Using the x-flag, Python3.3 and above
...     f.write('Hello\n')

>>> if not os.path.exists('somefile'): 
...     with open('somefile', 'wt') as f:
...         f.write("Hello\n")
... else:
...     print('File already exists!')



Additionally, os.access() :

if os.access("myfile", os.R_OK):
    with open("myfile") as fp:
        return fp.read()

Being R_OK , W_OK , and X_OK the flags to test for permissions ( doc ).




You can use the "OS" library of Python:

>>> import os
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.txt") 
True
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.tx")
False



Links



Tags

python python   file