python - كيف أتحقق من وجود ملف بدون استثناء؟




file file-exists (25)

لا يبدو أن هناك اختلافًا وظيفيًا ذا معنى بين المحاولة / 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'

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

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


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

يعتبر رفع الاستثناءات مقاربة مقبولة ، ومقاربة Pythonic للتحكم في التدفق في برنامجك. النظر في التعامل مع الملفات المفقودة مع IOErrors. في هذه الحالة ، سيتم رفع استثناء IOError في حالة وجود الملف ولكن ليس لدى المستخدم أذونات القراءة.

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


يمكنك استخدام مكتبة "OS" الخاصة بـ Python:

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

كيف أتحقق من وجود ملف ، باستخدام Python ، بدون استخدام عبارة المحاولة؟

متوفر الآن منذ Python 3.4 ، استيراد is_file كائن Path مع اسم الملف ، والتحقق من طريقة is_file (لاحظ أن هذا يرجع True is_file الرمزية التي تشير إلى الملفات العادية أيضًا):

>>> from pathlib import Path
>>> Path('/').is_file()
False
>>> Path('/initrd.img').is_file()
True
>>> Path('/doesnotexist').is_file()
False

إذا كنت تستخدم Python 2 ، فيمكنك backport module pathlib من pypi أو pathlib2 أو بطريقة أخرى التحقق من isfile من الوحدة os.path :

>>> import os
>>> os.path.isfile('/')
False
>>> os.path.isfile('/initrd.img')
True
>>> os.path.isfile('/doesnotexist')
False

الآن ، ربما يكون الجواب أعلاه هو أفضل إجابة عملية واقعية هنا ، ولكن هناك احتمال وجود حالة سباق (اعتمادًا على ما تحاول تحقيقه) ، وحقيقة أن التنفيذ الأساسي يستخدم try ، لكن Python تستخدم try في كل مكان التنفيذ.

ولأن بايثون تستخدم try كل مكان ، فلا يوجد سبب حقيقي لتجنب التنفيذ الذي يستخدمه.

لكن بقية هذه الإجابة تحاول النظر في هذه التحذيرات.

الجواب الأطول أكثر من ذلك بكثير

متوفر منذ Python 3.4 ، استخدم كائن Path الجديد في pathlib . لاحظ أن .exists ليس صحيحًا تمامًا ، نظرًا لأن الدلائل ليست ملفات (باستثناء إحساس Unix بأن كل شيء هو ملف).

>>> from pathlib import Path
>>> root = Path('/')
>>> root.exists()
True

لذلك نحن بحاجة إلى استخدام is_file :

>>> root.is_file()
False

إليك المساعدة على is_file :

is_file(self)
    Whether this path is a regular file (also True for symlinks pointing
    to regular files).

لذلك دعونا نحصل على ملف نعرفه هو ملف:

>>> import tempfile
>>> file = tempfile.NamedTemporaryFile()
>>> filepathobj = Path(file.name)
>>> filepathobj.is_file()
True
>>> filepathobj.exists()
True

بشكل افتراضي ، يحذف NamedTemporaryFile الملف عند إغلاق ( NamedTemporaryFile تلقائياً عند وجود لم مراجع أكثر).

>>> del file
>>> filepathobj.exists()
False
>>> filepathobj.is_file()
False

إذا قمت is_file في التطبيق ، is_file أن استخدامات is_file try :

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

شروط السباق: لماذا نحب المحاولة

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

إذا كنت تريد التحقق من وجود ملف قبل محاولة قراءته ، وقد تكون قد قمت بحذفه ، ومن ثم قد تستخدم عدة سلاسل عمليات أو عمليات ، أو إذا كان هناك برنامج آخر يعرف ذلك الملف ويمكن حذفه - فأنت بذلك تخاطر بفرصة شرط سباق إذا تحقق من وجودها ، لأنك تتسابق على فتحها قبل أن تتغير حالتها (وجودها).

من الصعب جدًا تصحيح أخطاء الأجناس بسبب وجود نافذة صغيرة جدًا يمكن أن تتسبب في فشل برنامجك.

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

تجنب شروط السباق دون بيان المحاولة: suppress

يعطينا Python 3.4 مدير السياق suppress (الذي كان في السابق ignore مدير السياق) ، والذي يقوم بالضبط بنفس الشيء في أسطر أقل ، في حين أنه (على الأقل بشكل سطحي) يلتقي بالسؤال الأصلي لتفادي بيان try :

from contextlib import suppress
from pathlib import Path

الاستعمال:

>>> with suppress(OSError), Path('doesnotexist').open() as f:
...     for line in f:
...         print(line)
... 
>>>
>>> with suppress(OSError):
...     Path('doesnotexist').unlink()
... 
>>> 

بالنسبة إلى بايثون سابقة ، يمكنك أن تقلل من قمعك الخاص ، ولكن بدون try سيكون ذلك أكثر دقة من ذلك. أعتقد أن هذا هو في الواقع الإجابة الوحيدة التي لا تستخدم try على أي مستوى في Python التي يمكن تطبيقها على Python 3.4 قبل أن تستخدم مدير سياق بدلاً من ذلك:

class suppress(object):
    def __init__(self, *exceptions):
        self.exceptions = exceptions
    def __enter__(self):
        return self
    def __exit__(self, exc_type, exc_value, traceback):
        if exc_type is not None:
            return issubclass(exc_type, self.exceptions)

ربما أسهل مع محاولة:

from contextlib import contextmanager

@contextmanager
def suppress(*exceptions):
    try:
        yield
    except exceptions:
        pass

خيارات أخرى لا تتوافق مع طلب "بدون تجربة":

isfile

import os
os.path.isfile(path)

من docs :

os.path.isfile(path)

إرجاع True إذا كان path هو ملف عادي موجود. هذا يتبع الارتباطات الرمزية ، بحيث يكون كل من islink() و isfile() صحيحًا لنفس المسار.

ولكن إذا قمت بفحص source هذه الوظيفة ، فسترى أنها تستخدم بالفعل عبارة المحاولة:

# This follows symbolic links, so both islink() and isdir() can be true
# for the same path on systems that support symlinks
def isfile(path):
    """Test whether a path is a regular file"""
    try:
        st = os.stat(path)
    except os.error:
        return False
    return stat.S_ISREG(st.st_mode)
>>> OSError is os.error
True

كل ما يفعله هو استخدام المسار المعين لمعرفة ما إذا كان بإمكانه الحصول على الإحصائيات عليه ، OSError ومن ثم التحقق مما إذا كان ملفًا إذا لم يرفع الاستثناء.

إذا كنت تنوي القيام بشيء ما مع الملف ، فإنني أقترح محاولة مباشرة لمحاولة تجنب أي شرط سباق:

try:
    with open(path) as f:
        f.read()
except OSError:
    pass

os.access

متاح لـ Unix و Windows هو os.access ، ولكن يجب عليك استخدام العلامات ، ولا يفرق بين الملفات والدلائل. هذا أكثر استخدامًا لاختبار ما إذا كان مستخدم الاستدعاء الحقيقي لديه حق الوصول في بيئة امتياز مرتفعة:

import os
os.access(path, os.F_OK)

كما يعاني من نفس المشاكل الشرط العرق كما isfile . من docs :

ملاحظة: استخدام الوصول () للتحقق مما إذا كان المستخدم مخولًا لفتح الملف مثلاً قبل القيام بذلك فعلاً باستخدام open () ينشئ ثغرة أمنية ، لأن المستخدم قد يستغل الفترة الزمنية القصيرة بين التحقق من الملف وفتحه للتلاعب به. من الأفضل استخدام تقنيات EAFP. فمثلا:

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

مكتوبة بشكل أفضل على النحو التالي:

try:
    fp = open("myfile")
except IOError as e:
    if e.errno == errno.EACCES:
        return "some default data"
    # Not a permission error.
    raise
else:
    with fp:
        return fp.read()

تجنب استخدام os.access . وهي دالة منخفضة المستوى لها المزيد من الفرص لخطأ المستخدم أكثر من الكائنات ووظائف المستوى الأعلى التي نوقشت أعلاه.

انتقاد إجابة أخرى:

إجابة أخرى تقول هذا عن os.access :

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

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

كما أنه ينشئ أيضًا مديرًا للطقس يسمح ، من خلال إرجاع True غير مشروط ، لجميع الاستثناءات (بما في ذلك KeyboardInterrupt و SystemExit !) بالمرور بصمت ، وهي طريقة جيدة لإخفاء الأخطاء.

يبدو أن هذا يشجع المستخدمين على تبني الممارسات السيئة.


استخدم os.path.isfile() مع os.access() :

import os
import os.path

PATH='./file.txt'

if os.path.isfile(PATH) and os.access(PATH, os.R_OK):
    print "File exists and is readable"
else:
    print "Either the file is missing or not readable"

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

import os
fname = "foo.txt"
if os.path.isfile(fname):
    print("file does exist at this time")
else:
    print("no such file exists at this time")

إضافة تباين طفيف آخر لا ينعكس تمامًا في الإجابات الأخرى.

سيعالج هذا حالة file_pathالكينونة Noneأو السلسلة الفارغة.

def file_exists(file_path):
    if not file_path:
        return False
    elif not os.path.isfile(file_path):
        return False
    else:
        return True

إضافة متغير بناءً على اقتراح من شهباز

def file_exists(file_path):
    if not file_path:
        return False
    else:
        return os.path.isfile(file_path)

إضافة متغير بناءً على اقتراح من بيتر وود

def file_exists(file_path):
    return file_path and os.path.isfile(file_path):

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 باستخدام النقطة:

# 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

بعكس isfile() ، isfile() exists() True isfile() .
بناءً على ما إذا كنت تريد ملفات عادية فقط أو أيضًا أدلة ، ستستخدم isfile() أو exists() . هنا هو إخراج REPL بسيط.

>>> print os.path.isfile("/etc/password.txt")
True
>>> print os.path.isfile("/etc")
False
>>> print os.path.isfile("/does/not/exist")
False
>>> print os.path.exists("/etc/password.txt")
True
>>> print os.path.exists("/etc")
True
>>> print os.path.exists("/does/not/exist")
False

تفضل بيان المحاولة. يعتبر أسلوبًا أفضل ويتجنب ظروف السباق.

لاتأخذ كلماتي على محمل الجد. هناك الكثير من الدعم لهذه النظرية. وهنا زوجين:


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

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

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


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

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

هذا إرجاع True لكلا الملفين والأدلة ولكن يمكنك بدلاً من ذلك استخدام

os.path.isfile(file_path)

لاختبار ما إذا كان ملفًا على وجه التحديد. يتبع symlinks.


تاريخ: 2017/12/04

تم سرد كل الحلول الممكنة في إجابات أخرى.

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

import os
os.path.isfile('~/file.md')    # Returns True if exists, else False
additionaly check a dir
os.path.isdir('~/folder') # Returns True if the folder exists, else False
check either a dir or a file
os.path.exists('~/file')

لقد قدمت chitesheet شاملة للرجوع اليها:

#os.path methods in exhaustive cheatsheet
{'definition': ['dirname',
               'basename',
               'abspath',
               'relpath',
               'commonpath',
               'normpath',
               'realpath'],
'operation': ['split', 'splitdrive', 'splitext',
               'join', 'normcase'],
'compare': ['samefile', 'sameopenfile', 'samestat'],
'condition': ['isdir',
              'isfile',
              'exists',
              'lexists'
              'islink',
              'isabs',
              'ismount',],
 'expand': ['expanduser',
            'expandvars'],
 'stat': ['getatime', 'getctime', 'getmtime',
          'getsize']}

إذا قمت باستيراد NumPy بالفعل لأغراض أخرى ، فلا داعي لاستيراد مكتبات أخرى مثل pathlib، osو paths، وما إلى ذلك.

import numpy as np
np.DataSource().exists("path/to/your/file")

سيعود هذا صوابًا أو خطأ استنادًا إلى وجوده.


في عام 2016 ، لا تزال أفضل طريقة تستخدم os.path.isfile :

>>> os.path.isfile('/path/to/some/file.txt')

أو في Python 3 يمكنك استخدام pathlib :

import pathlib
path = pathlib.Path('/path/to/some/file.txt')
if path.is_file():
    ...

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

>>> 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!')

تحديث

فقط لتفادي الخلط واستنادا إلى الإجابات التي حصلت عليها ، تجد الإجابة الحالية إما ملفًا أو دليلًا بالاسم المحدد.


تحقق من وجود ملف أو دليل

يمكنك اتباع هذه الطرق الثلاث:

Note1: os.path.isfileيستخدم فقط للملفات

import os.path
os.path.isfile(filename) # True if file exists
os.path.isfile(dirname) # False if directory exists

Note2: os.path.existsالمستخدمة لكل من الملفات والدلائل

import os.path
os.path.exists(filename) # True if file exists
os.path.exists(dirname) #True if directory exists

على pathlib.Pathطريقة (المدرجة في بيثون 3+، للتثبيت مع نقطة لبيثون 2)

from pathlib import Path
Path(filename).exists()

اختبار الملفات والمجلدات باستخدام os.path.isfile() و os.path.isdir() و os.path.exists()

بافتراض أن "المسار" هو مسار صالح ، يوضح هذا الجدول ما يتم إرجاعه من خلال كل وظيفة للملفات والمجلدات:

يمكنك أيضًا اختبار ما إذا كان الملف نوعًا معينًا من الملفات باستخدام os.path.splitext() للحصول على الامتداد (إذا لم تكن تعرفه بالفعل)

>>> import os
>>> path = "path to a word document"
>>> os.path.isfile(path)
True
>>> os.path.splitext(path)[1] == ".docx" # test if the extension is .docx
True

على الرغم من أنني دائما نوصي باستخدام tryو exceptالتصريحات، وهنا بعض الاحتمالات بالنسبة لك (قناعتي الشخصية المفضلة يستخدم os.access):

  1. حاول فتح الملف:

    دائمًا ما يؤدي فتح الملف إلى التحقق من وجود الملف. يمكنك إنشاء وظيفة تمامًا مثل:

    def File_Existence(filepath):
        f = open(filepath)
        return True
    

    إذا كان False ، فإنه سيتم إيقاف التنفيذ مع IOError unhanded أو OSError في الإصدارات الأحدث من Python. للقبض على الاستثناء ، يجب عليك استخدام المحاولة باستثناء جملة. بالطبع ، يمكنك دائمًا استخدام عبارة " tryباستثناء" مثل ذلك (بفضل hsandt أفكر):

    def File_Existence(filepath):
        try:
            f = open(filepath)
        except IOError, OSError: # Note OSError is for later versions of Python
            return False
    
        return True
    
  2. الاستخدام os.path.exists(path):

    هذا سوف يتحقق من وجود ما تحدده. ومع ذلك، فإنه يتحقق للملفات و الدلائل حذار جدا حول كيفية استخدامه.

    import os.path
    >>> os.path.exists("this/is/a/directory")
    True
    >>> os.path.exists("this/is/a/file.txt")
    True
    >>> os.path.exists("not/a/directory")
    False
    
  3. الاستخدام os.access(path, mode):

    سيتحقق هذا مما إذا كان لديك حق الوصول إلى الملف. وسوف تحقق من وجود أذونات. استنادًا إلى وثائق os.py ، مكتوبة ، os.F_OKستتحقق من وجود المسار. ومع ذلك ، يؤدي استخدام هذا إلى إنشاء ثقب أمان ، حيث يمكن لأي شخص مهاجمة الملف باستخدام الوقت بين التحقق من الأذونات وفتح الملف. يجب بدلاً من ذلك الانتقال مباشرة إلى فتح الملف بدلاً من التحقق من الأذونات الخاصة به. ( EAFP vs LBYP ). إذا كنت لن تفتح الملف بعد ذلك ، وفحصت فقط من وجوده ، فيمكنك استخدام هذا.

    على أي حال ، هنا:

    >>> import os
    >>> os.access("/is/a/file.txt", os.F_OK)
    True
    

يجب أن أذكر أيضا أن هناك طريقتين لن تتمكن من التحقق من وجود ملف. إما أن تكون المشكلة permission deniedأو no such file or directory. إذا قمت بالقبض IOError، فقم بتعيين IOError as e(مثل الخيار الأول) ، ثم اكتب في print(e.args)بحيث يمكنك تحديد مشكلتك على أمل. اتمني ان يكون مفيدا! :)


أنا مؤلف حزمة كانت موجودة منذ حوالي 10 سنوات ، ولها وظيفة تعالج هذا السؤال بشكل مباشر. في الأساس ، إذا كنت تستخدم نظامًا غير Windows ، فإنه يستخدم Popenللوصول find. ومع ذلك ، إذا كنت تعمل على نظام تشغيل Windows ، فإنه يتم إجراء نسخ متماثل لها findباستخدام برنامج walker فعال.

لا يستخدم الكود في حد ذاته tryكتلة ... إلا في تحديد نظام التشغيل ومن ثم findتوجيهك إلى نمط "Unix" أو buillt اليد find. أظهرت اختبارات التوقيت أن tryالسرعة كانت أسرع في تحديد نظام التشغيل ، لذا فقد استخدمت واحدة هناك (ولكن في أي مكان آخر).

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

والوثيقة ...

>>> 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']

>>>

التطبيق ، إذا كنت ترغب في البحث ، هنا: https://github.com/uqfoundation/pox/blob/89f90fb308f285ca7a62eabe2c38acb87e89dad9/pox/shutils.py#L190


كيف أتحقق من وجود ملف ، بدون استخدام بيان المحاولة؟

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

import os
os.path.isfile('./file.txt')    # Returns True if exists, else False

isfileهو في الواقع مجرد أسلوب مساعد يستخدم داخليا os.statو stat.S_ISREG(mode)تحتها. هذه os.statطريقة منخفضة المستوى توفر لك معلومات مفصلة حول الملفات والدلائل والمقابس والمخازن المؤقتة والمزيد. المزيد عن os.stat هنا

ملاحظة: على الرغم من ذلك ، لن يؤدي هذا النهج إلى تأمين الملف بأي طريقة ، وبالتالي يمكن أن تصبح التعليمات البرمجية الخاصة بك عرضةً لأخطاء " وقت التحقق إلى وقت الاستخدام " ( TOCTTOU ).

لذا يعتبر رفع الاستثناءات مقاربة مقبولة ، ومقاربة Pythonic للتحكم في التدفق في برنامجك. وينبغي للمرء النظر في التعامل مع الملفات المفقودة مع IOErrors ، بدلا من ifالبيانات ( مجرد نصيحة ).


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


بالإضافة إلى ذلك ، os.access():

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

ويجري R_OK، W_OKو X_OKأعلام لاختبار للحصول على أذونات ( وثيقة ).


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

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

الخلاصة :

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

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

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

إذا كان أي شخص يبحث عن شيء أكثر تقدمًا ، جرّب RequireJS . ستحصل على فوائد إضافية مثل إدارة التبعية ، والتزام أفضل ، وتجنب الازدواجية (أي ، استرداد برنامج نصي أكثر من مرة واحدة).

يمكنك كتابة ملفات جافا سكريبت في "الوحدات النمطية" ثم الرجوع إليها كتركيبات في النصوص الأخرى. أو يمكنك استخدام RequireJS كحل بسيط "go get get".

مثال:

تعريف التبعيات كوحدات:

بعض-dependency.js

define(['lib/dependency1', 'lib/dependency2'], function (d1, d2) {

     //Your actual script goes here.   
     //The dependent scripts will be fetched if necessary.

     return libraryObject;  //For example, jQuery object
});

يعد ملف التنفيذ.js هو ملف جافا سكريبت "الرئيسي" الذي يعتمد على بعض dependency.js

require(['some-dependency'], function(dependency) {

    //Your script goes here
    //some-dependency.js is fetched.   
    //Then your script is executed
});

مقتطفات من GitHub README:

RequireJS يقوم بتحميل ملفات JavaScript بسيطة بالإضافة إلى وحدات أكثر تحديدًا. تم تحسينه للاستخدام داخل المتصفح ، بما في ذلك في Web Worker ، ولكن يمكن استخدامه في بيئات JavaScript أخرى ، مثل Rhino و Node. إنها تطبق API الوحدة النمطية المتزامنة.

يستخدم RequireJS علامات برنامج نصي بسيط لتحميل الوحدات / الملفات ، لذلك يجب أن يسمح لتصحيح الأخطاء بسهولة. يمكن استخدامه ببساطة لتحميل ملفات JavaScript الموجودة ، حتى يمكنك إضافتها إلى مشروعك الحالي دون الحاجة إلى إعادة كتابة ملفات JavaScript.

...







python file file-exists