सवाल मैं कैसे जांचूं कि कोई फ़ाइल मौजूद है या नहीं?


मैं कैसे देख सकता हूं कि फ़ाइल का उपयोग किए बिना या नहीं है try बयान?


4361
2017-09-17 12:55


मूल




जवाब:


यदि आप जिस कारण की जांच कर रहे हैं तो आप ऐसा कुछ कर सकते हैं if file_exists: open_it(), इसका उपयोग करना सुरक्षित है try इसे खोलने के प्रयास के आसपास। फ़ाइल को हटाया जा रहा है या स्थानांतरित किया जा रहा है या जब आप जांचते हैं और जब आप इसे खोलने का प्रयास करते हैं तो कुछ जोखिम खुलता है।

यदि आप तुरंत फ़ाइल खोलने की योजना नहीं बना रहे हैं, तो आप इसका उपयोग कर सकते हैं os.path.isfile

वापसी True यदि पथ एक मौजूदा नियमित फ़ाइल है। यह प्रतीकात्मक लिंक का पालन करता है, तो दोनों islink () तथा isfile () एक ही रास्ते के लिए सच हो सकता है।

import os.path
os.path.isfile(fname) 

अगर आपको यह सुनिश्चित करने की ज़रूरत है कि यह एक फाइल है।

पायथन 3.4 से शुरू, द pathlib मॉड्यूल ऑब्जेक्ट उन्मुख दृष्टिकोण प्रदान करता है (को वापस भेज दिया गया pathlib2 पायथन 2.7 में:

from pathlib import Path

my_file = Path("/path/to/file")
if my_file.is_file():
    # file exists

निर्देशिका जांचने के लिए, करें:

if my_file.is_dir():
    # directory exists

यह जांचने के लिए कि क्या Path वस्तु स्वतंत्र रूप से मौजूद है चाहे वह एक फ़ाइल या निर्देशिका है, उपयोग करें exists():

if my_file.exists():
    # path exists

आप भी उपयोग कर सकते हैं resolve() में try ब्लॉक:

try:
    my_abs_path = my_file.resolve()
except FileNotFoundError:
    # doesn't exist
else:
    # exists

3963
2017-09-17 12:57



पहली टिप्पणी के संबंध में (यदि खोलने से पहले चेक करें तो "कोशिश करें" का उपयोग करें) दुर्भाग्यवश यह काम नहीं करेगा यदि आप यह सुनिश्चित करने के लिए खोलना चाहते हैं कि 'ए' मोड मौजूद नहीं होने के बाद से मौजूद है। - makapuf
मुझे मिला os.path.isfile अस्तित्व में नहीं है - JeromeJ


आपके पास है os.path.exists समारोह:

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

यह रिटर्न True दोनों फाइलों और निर्देशिकाओं के लिए लेकिन आप इसके बजाय उपयोग कर सकते हैं

os.path.isfile(file_name)

यह जांचने के लिए कि क्या यह विशेष रूप से एक फ़ाइल है। यह सिम्लिंक का पालन करता है।


1626
2017-09-17 12:57





भिन्न isfile(), exists() वापस होगा True निर्देशिका के लिए।
तो यदि आप केवल सादे फाइलों या निर्देशिकाओं को चाहते हैं, तो आप इसका उपयोग करेंगे isfile() या exists()। यहां एक साधारण आरईपीएल आउटपुट है।

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

837
2017-09-17 15:01





import os.path

if os.path.isfile(filepath):

468
2017-09-17 12:55





उपयोग 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"

223
2018-01-16 05:57



कई स्थितियां हैं, जिनमें से कुछ अनिवार्य हैं, है कम से स्पष्ट और स्पष्ट। - wim
यह भी अनावश्यक है। अगर फ़ाइल मौजूद नहीं है, os.access() झूठी वापसी होगी। - user207421
@EJP लिनक्स फाइलों में मौजूद हो सकता है लेकिन एक्सेसिबल नहीं है। - e-info128


import os
os.path.exists(path) # Returns whether the path (directory or file) exists or not
os.path.isfile(path) # Returns whether the file exists or not

209
2017-09-17 12:56



यह जवाब गलत है। os.path.exists उन चीज़ों के लिए सत्य लौटाता है जो निर्देशिका नहीं हैं, जैसे निर्देशिकाएं। यह झूठी सकारात्मक देता है। अनुशंसा करते हुए अन्य उत्तरों देखें os.path.isfile। - Chris Johnson
एक निर्देशिका फ़ाइल का एक प्रकार है unix.stackexchange.com/questions/197439/... - James Roth


फ़ाइल मौजूद है या नहीं यह जांचने का सबसे आसान तरीका है। केवल इसलिये जब आप चेक नहीं करते हैं तो फाइल मौजूद थी गारंटी जब आपको इसे खोलने की आवश्यकता होगी तो यह वहां होगा।

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

139
2018-06-27 13:38



जब तक आप फ़ाइल तक पहुंचने का इरादा रखते हैं, दौड़ की स्थिति अस्तित्व में है, इस पर ध्यान दिए बिना कि आपका प्रोग्राम कैसे बनाया गया है। आपका प्रोग्राम गारंटी नहीं दे सकता कि कंप्यूटर पर एक और प्रक्रिया ने फाइल को संशोधित नहीं किया है। यह एरिक लिपर्ट को एक के रूप में संदर्भित करता है exogenous अपवाद। आप फ़ाइल के अस्तित्व की जांच करके पहले से बच नहीं सकते हैं। - Isaac Supeene
@IsaacSupeene सर्वोत्तम अभ्यास (फ़ाइल) ऑपरेशन की खिड़की को जितना संभव हो सके उतना छोटा बनाना है जिसके बाद उचित अपवाद हैंडलिंग - un33k


2017/12/22:

यद्यपि लगभग हर संभव तरीके से मौजूदा उत्तरों (उदा। कम से कम एक) में सूचीबद्ध किया गया है (उदा। पायथन 3.4 विशिष्ट सामान जोड़ा गया था), मैं सबकुछ एक साथ समूह करने की कोशिश करूंगा।

ध्यान दें: का हर टुकड़ा अजगर मानक लाइब्रेरी कोड जो मैं पोस्ट करने जा रहा हूं, संस्करण से संबंधित है 3.5.3 (डॉक्टर उद्धरण संस्करण हैं 3 विशिष्ट)।

समस्या का विवरण:

  1. फ़ाइल जांचें (विवाद-योग्य: फ़ोल्डर ("विशेष" फ़ाइल)?) अस्तित्व
  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 चारों ओर ब्लॉक करें [पायथन]: ओएस।स्टेट(पथ, *, dir_fd = कोई नहीं, follow_symlinks = सही है)। तो, आपका कोड है try/except मुफ़्त, लेकिन framestack में कम है (कम से कम) एक ऐसा ब्लॉक यह अन्य funcs पर भी लागू होता है (समेत  os.path.isfile)।

    1.1। [पायथन]: pathlib.Path।is_file()

    • यह एक प्रशंसक है (और अधिक अजगरआईसी) पथों को संभालने का तरीका, परंतु
    • हुड के तहत, यह करता है ठीक ठीक वही चीज़ (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 व्यवहार (ध्यान दें कि यह केवल उद्देश्यों को प्रदर्शित करने के लिए है, करते हैं नहीं इस तरह के कोड लिखने का प्रयास करें उत्पादन):

        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 ब्लॉक, के रूप में [पायथन]: द साथ में बयान कहा गया है:

    यह आम अनुमति देता है प्रयत्न...के सिवाय...आखिरकार सुविधाजनक पुन: उपयोग के लिए उपयोग पैटर्न encapsulated करने के लिए।

  3. फाइलसिस्टम ट्रैवर्सल फ़ंक्शंस (और मेल खाने वाले आइटम के लिए परिणाम खोजें)


    चूंकि ये फ़ोल्डरों पर पुनरावृत्त होते हैं, (ज्यादातर मामलों में) वे हमारी समस्या के लिए अक्षम हैं (अपवाद हैं, जैसे गैर वाइल्डकार्ड globबिंग - जैसा कि @ShadowRanger ने बताया), इसलिए मैं उन पर जोर देने वाला नहीं हूं। उल्लेख नहीं है कि कुछ मामलों में, फ़ाइल नाम प्रसंस्करण की आवश्यकता हो सकती है।

  4. [पायथन]: ओएस।पहुंच(पथ, मोड, *, dir_fd = कोई नहीं, प्रभावी_आईडी = गलत, follow_symlinks = सही) जिसका व्यवहार करीब है os.path.exists (वास्तव में यह व्यापक है, मुख्य रूप से 2 की वजह सेnd तर्क)

    • उपयोगकर्ता अनुमतियां दस्तावेज के रूप में फ़ाइल "दृश्यता" को प्रतिबंधित कर सकते हैं:

      ... परीक्षण अगर आवेदक उपयोगकर्ता के पास निर्दिष्ट पहुंच है पथमोड होना चाहिए F_OK पथ के अस्तित्व का परीक्षण करने के लिए ...

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

    चूंकि मैं भी काम करता हूं सी, मैं इस विधि का भी उपयोग करता हूं क्योंकि हुड के नीचे, यह कॉल करता है देशी एपीआईरों (फिर से, के माध्यम से "$ {PYTHON_SRC_DIR} /Modules/posixmodule.c"), लेकिन यह भी संभव के लिए एक द्वार खोलता है उपयोगकर्ता त्रुटियां, और यह नहीं है अजगरआईसी अन्य रूपों के रूप में। तो, जैसा कि @AaronHall ने सही ढंग से इंगित किया है, इसका उपयोग न करें जबतक कि आप यह नहीं जानते कि आप क्या कर रहे हैं:

    ध्यान दें: देशी कॉलिंग एपीआईएस के माध्यम से भी संभव है [अजगर]: ctypes - पायथन के लिए एक विदेशी समारोह पुस्तकालय, लेकिन ज्यादातर मामलों में यह अधिक जटिल है।

    (जीत विशिष्ट): के बाद से msvcr *(vcruntime *) एक निर्यात करता है [एमएसडीएन]: _access, _waccess समारोह परिवार भी, यहां एक उदाहरण है:

    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 (बावजूद यूनिकोड उनके बीच संबंधित अंतर)
    • हालांकि यह एक बहुत ही विशिष्ट क्षेत्र को लक्षित करता है, पिछले किसी भी उत्तर में इसका उल्लेख नहीं किया गया था


    lnx (उबतु (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 (या खाली स्ट्रिंग) को पारित किया जा सकता है CDLL कन्स्ट्रक्टर (ctypes.CDLL(None).access(b"/tmp", os.F_OK))। इसके अनुसार [आदमी]: डोलपेन (3):

      अगर फ़ाइल का नाम शून्य है, तो लौटा संभाल मुख्य के लिए है   कार्यक्रम। जब दिया जाता है dlsym(), यह संभाल एक के लिए एक खोज का कारण बनता है   मुख्य कार्यक्रम में प्रतीक, उसके बाद लोड की गई सभी साझा वस्तुओं के बाद   कार्यक्रम स्टार्टअप, और फिर सभी साझा वस्तुओं द्वारा लोड किया गया dlopen() साथ में   झंडा RTLD_GLOBAL

      • मुख्य (वर्तमान) कार्यक्रम (अजगर) के खिलाफ जुड़ा हुआ है libc, तो इसके प्रतीक (सहित access) लोड हो जाएगा
      • इस तरह के कार्यों के बाद, इसे देखभाल के साथ संभाला जाना है main, Py_Main और (सभी) अन्य उपलब्ध हैं; उन्हें बुलाकर विनाशकारी प्रभाव हो सकते हैं (वर्तमान कार्यक्रम पर)
      • यह भी लागू नहीं होता है जीत (लेकिन यह तब से इतना बड़ा सौदा नहीं है msvcrt.dllइसमें स्थित है "% SystemRoot% \ System32" जो की अंदर है % पथ% डिफ़ॉल्ट रूप से)। मैं चीजों को आगे ले जाना चाहता था और इस व्यवहार को दोहराना चाहता था जीत (और एक पैच जमा करें), लेकिन जैसा कि यह पता चला है, [एमएसडीएन]: GetProcAddress समारोह केवल "देखता है" निर्यात प्रतीकों, इसलिए जब तक कोई मुख्य निष्पादन योग्य में कार्यों की घोषणा नहीं करता है __declspec(dllexport) (पृथ्वी पर क्यों नियमित व्यक्ति ऐसा करेगा?), मुख्य कार्यक्रम लोड करने योग्य है लेकिन काफी ज्यादा उपयोग करने योग्य है
  5. कुछ 3 स्थापित करेंतृतीय फाइल सिस्टम क्षमताओं के साथ पार्टी मॉड्यूल

    सबसे अधिक संभावना है, उपरोक्त तरीकों में से एक पर निर्भर करेगा (शायद मामूली अनुकूलन के साथ)।
    एक उदाहरण होगा (फिर से, जीत विशिष्ट) [गिटहब]: विंडोज़ के लिए पायथन (पायविन 32) एक्सटेंशन, जो कि है अजगर रैपर खत्म WINAPIरों।

    लेकिन, चूंकि यह एक कामकाज की तरह है, इसलिए मैं यहां रोक रहा हूं।

  6. एक और (लंगड़ा) कामकाज (gainarie) है (जैसा कि मैं इसे कॉल करना चाहता हूं,) सिस्टम प्रशासक दृष्टिकोण: उपयोग करें अजगर खोल कमांड निष्पादित करने के लिए एक रैपर के रूप में

    • जीत:

      (py35x64_test) e:\Work\Dev\StackOverflow\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\StackOverflow\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 ब्लॉक, क्योंकि वे आपको खराब समस्याओं की एक श्रृंखला में भागने से रोक सकते हैं। एक काउंटर-उदाहरण जिसे मैं सोच सकता हूं, प्रदर्शन है: ऐसे ब्लॉक महंगे हैं, इसलिए उन्हें कोड में न रखने की कोशिश करें कि यह प्रति सेकंड सैकड़ों हजार बार चलाना है (लेकिन अधिकांश मामलों में) इसमें डिस्क एक्सेस शामिल है, यह मामला नहीं होगा)।

अंतिम नोट:

  • मैं इसे अद्यतित रखने की कोशिश करूंगा, किसी भी सुझाव का स्वागत है, मैं कुछ उपयोगी भी शामिल करूंगा जो उत्तर में आ जाएगा

137
2018-06-20 19:28



क्या आप इस कथन पर विस्तार कर सकते हैं? "हालांकि यह एक अच्छा अभ्यास नहीं है, मैं कॉल में os.F_OK का उपयोग कर रहा हूं, लेकिन यह केवल स्पष्टता के लिए है (इसका मान 0 है)" - sk8asd123
@ sk8asd123: किसी टिप्पणी में इसे करने के लिए कड़ी मेहनत की तरह: आम तौर पर, उन कार्यों के साथ स्थिरांक का उपयोग करना सर्वोत्तम होता है जो वे साथ आते हैं। यह तब लागू होता है जब एक ही स्थिरता को परिभाषित करने वाले एकाधिक मॉड्यूल के साथ काम करते हैं, क्योंकि कुछ अद्यतित नहीं हो सकते हैं, और कार्यों और स्थिरांक के लिए यह सर्वोत्तम है। काम करते समय ctypes (सीधे कार्यों को बुलावा) मुझे निरंतर परिभाषित करना चाहिए था (से MSDN), या निरंतर उपयोग नहीं करते हैं। यह केवल एक दिशानिर्देश है जिसका मैं उपयोग करता हूं, 99.9% में यह संभवतः कोई फर्क नहीं पड़ता (कार्यात्मक रूप से)। - CristiFati
@ क्रिस्टीफाटी: 3.6 के रूप में, glob.iglob (तथा glob.glob साथ ही) पर आधारित हैं os.scandir, तो अब यह आलसी है; 10 एम फ़ाइलों की निर्देशिका में पहली हिट प्राप्त करने के लिए, आप केवल तब तक स्कैन करते हैं जब तक आप पहली हिट तक नहीं पहुंच जाते। और यदि आप उपयोग करते हैं तो भी प्री-3.6 glob किसी भी वाइल्डकार्ड w / o विधियों, समारोह स्मार्ट है: यह जानता है कि आप केवल एक हिट कर सकते हैं, तो यह सिर्फ globbing को सरल बनाता है os.path.isdir या os.path.lexists (इस पर निर्भर करता है कि पथ समाप्त होता है या नहीं /)। - ShadowRanger
मेरी टिप्पणी का वह दूसरा भाग (गैर-वाइल्डकार्ड ग्लोबिंग वास्तव में फ़ोल्डर को पुन: सक्रिय नहीं करता है, और कभी नहीं) का मतलब है कि यह समस्या का एक बिल्कुल प्रभावी समाधान है (सीधे कॉल करने से धीमा os.path.isdir या os.path.lexist चूंकि यह पाइथन स्तर फ़ंक्शन कॉल और स्ट्रिंग ऑपरेशंस का एक गुच्छा है, इससे पहले कि यह प्रभावी पथ तय कर सके, व्यवहार्य है, लेकिन कोई अतिरिक्त सिस्टम कॉल या I / O काम नहीं है, जो परिमाण धीमा होने का आदेश है)। - ShadowRanger


पायथन 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.')

पाथलिब मॉड्यूल में इसमें बहुत सी अच्छी चीजें हैं: सुविधाजनक ग्लोबिंग, फ़ाइल के मालिक की जांच करना, आसान पथ शामिल होना आदि। यह जांचना उचित है। यदि आप पुराने पायथन (संस्करण 2.6 या बाद में) पर हैं, तो आप अभी भी पाइप के साथ पाथलिब स्थापित कर सकते हैं:

# 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

121
2018-02-08 02:38





कोशिश कथन पसंद करते हैं। इसे बेहतर शैली माना जाता है और दौड़ की स्थिति से बचा जाता है।

इसके लिए मेरा शब्द मत लो। इस सिद्धांत के लिए बहुत सारे समर्थन हैं। यहां एक जोड़ा है:


111
2017-11-04 00:48



कृपया अपने कथन का समर्थन करने के लिए बेहतर स्रोत जोड़ें। - BlueTrin
उल्लिखित रेस स्थितियों (सेब देव समर्थन) लिंक उद्धृत आपके उत्तर का समर्थन नहीं करता है। यह केवल अस्थायी फ़ाइलों का उपयोग करने से संबंधित है जिसमें खराब डिजाइन किए गए ऑपरेटिंग सिस्टम पर संवेदनशील जानकारी होती है जो प्रतिबंधित अनुमतियों के माध्यम से अस्थायी फ़ाइलों / निर्देशिकाओं को सही ढंग से सैंडबॉक्स नहीं करते हैं। का उपयोग करते हुए try...except हल करने में मदद नहीं करता है उस वैसे भी समस्या। - jstine
हालांकि यह लिंक प्रश्न का उत्तर दे सकता है, लेकिन यहां उत्तर के आवश्यक हिस्सों को शामिल करना बेहतर है और संदर्भ के लिए लिंक प्रदान करना बेहतर है। लिंक किए गए पृष्ठ में परिवर्तन होने पर लिंक-केवल उत्तर अमान्य हो सकते हैं। - समीक्षा से - user3483203
@chrisz मुझे नहीं लगता कि यह केवल लिंक है - इसमें वास्तव में लिंक के अलावा अन्य जानकारी है। - EJoshuaS


मैं कोशिश कैसे करूं कि पाइथन का उपयोग किए बिना कोई फ़ाइल मौजूद है या नहीं, एक कोशिश कथन का उपयोग किए बिना?

अब पाइथन 3.4 के बाद उपलब्ध है, आयात और तत्काल एक Path फ़ाइल नाम के साथ ऑब्जेक्ट करें, और जांचें is_file विधि (ध्यान दें कि नियमित फ़ाइलों को इंगित करने वाले सिम्लिंक के लिए यह सही होता है):

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

यदि आप पाइथन 2 पर हैं, तो आप पाइपि से पाथलिब मॉड्यूल का बैकपोर्ट कर सकते हैं, pathlib2, या अन्यथा जांचें isfile वहाँ से os.path मॉड्यूल:

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

अब उपरोक्त शायद सबसे अच्छा व्यावहारिक प्रत्यक्ष उत्तर है, लेकिन दौड़ की स्थिति (जो आप पूरा करने की कोशिश कर रहे हैं उसके आधार पर) की संभावना है, और तथ्य यह है कि अंतर्निहित कार्यान्वयन एक try, लेकिन पायथन का उपयोग करता है try इसके कार्यान्वयन में हर जगह।

क्योंकि पाइथन का उपयोग करता है try हर जगह, इसका उपयोग करने वाले कार्यान्वयन से बचने के लिए वास्तव में कोई कारण नहीं है।

लेकिन बाकी का जवाब इन चेतावनियों पर विचार करने का प्रयास करता है।

लंबा, बहुत अधिक pedantic जवाब

पाइथन 3.4 के बाद उपलब्ध, नए का उपयोग करें Path में वस्तु pathlib। ध्यान दें कि .exists बिल्कुल सही नहीं है, क्योंकि निर्देशिका फाइल नहीं है (यूनिक्स समझ में छोड़कर सब कुछ एक फाइल है)।

>>> 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 बंद होने पर फ़ाइल को हटा देता है (और स्वचालित रूप से बंद हो जाएगा जब इसके लिए कोई और संदर्भ मौजूद नहीं है)।

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

यदि आप खोदते हैं कार्यान्वयनहालांकि, आप इसे देखेंगे 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

पायथन 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()
... 
>>> 

पहले पायथन के लिए, आप अपना खुद का रोल कर सकते हैं suppress, लेकिन बिना try के साथ अधिक verbose होगा। मुझे विश्वास है यह वास्तव में एकमात्र उत्तर है जिसका उपयोग नहीं करता है try पायथन में किसी भी स्तर पर जिसे पायथन 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)

वहाँ से डॉक्स:

os.path.isfile(path)

यदि पथ एक नियमित नियमित फ़ाइल है तो सत्य वापस लौटें। यह प्रतीकात्मक का पालन करता है   लिंक, तो दोनों islink() तथा isfile() एक ही रास्ते के लिए सच हो सकता है।

लेकिन अगर आप की जांच करते हैं स्रोतइस समारोह के, आप देखेंगे कि यह वास्तव में एक कोशिश कथन का उपयोग करता है:

# 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

यूनिक्स और विंडोज के लिए उपलब्ध है os.access, लेकिन उपयोग करने के लिए आपको झंडे पास करना होगा, और यह फाइलों और निर्देशिकाओं के बीच अंतर नहीं करता है। यह परीक्षण करने के लिए अधिक उपयोग किया जाता है कि वास्तविक आवेदक उपयोगकर्ता के पास एक उन्नत विशेषाधिकार वातावरण में पहुंच है या नहीं:

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

यह भी उसी दौड़ की स्थिति की समस्याओं से ग्रस्त है isfile। वहाँ से डॉक्स:

ध्यान दें:   यह देखने के लिए कि कोई उपयोगकर्ता उदास है या नहीं, यह एक्सेस () का उपयोग करना एक फ़ाइल खोलो   वास्तव में खुले () का उपयोग करके ऐसा करने से पहले एक सुरक्षा छेद बनाता है, क्योंकि   उपयोगकर्ता जांच के बीच कम समय अंतराल का फायदा उठा सकता है   फ़ाइल को हेरफेर करने के लिए खोलना। ईएएफपी का उपयोग करना बेहतर है   तकनीक। उदाहरण के लिए:

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!) चुपचाप गुजरने के लिए, जो बग को छिपाने का एक अच्छा तरीका है।

ऐसा लगता है कि उपयोगकर्ताओं को खराब प्रथाओं को अपनाने के लिए प्रोत्साहित किया जाता है।


101
2017-08-11 03:54