ฉันจะตรวจสอบว่าไฟล์มีอยู่หรือไม่โดยไม่ใช้tryคำสั่งได้อย่างไร
ฉันจะตรวจสอบว่าไฟล์มีอยู่หรือไม่โดยไม่ใช้tryคำสั่งได้อย่างไร
คำตอบ:
หากเหตุผลที่คุณตรวจสอบคือเพื่อให้คุณสามารถทำสิ่งต่างif file_exists: open_it()ๆ มันปลอดภัยกว่าที่จะใช้tryความพยายามในการเปิด การตรวจสอบและจากนั้นเปิดความเสี่ยงที่ไฟล์จะถูกลบหรือย้ายหรือบางสิ่งบางอย่างระหว่างเมื่อคุณตรวจสอบและเมื่อคุณพยายามที่จะเปิด
หากคุณไม่ได้วางแผนที่จะเปิดไฟล์ทันทีคุณสามารถใช้ os.path.isfile
ส่งคืน
Trueถ้าเส้นทางเป็นไฟล์ปกติที่มีอยู่ สิ่งนี้ตามลิงก์สัญลักษณ์ดังนั้นทั้งislink ()และisfile ()อาจเป็นจริงสำหรับพา ธ เดียวกัน
import os.path
os.path.isfile(fname)
หากคุณต้องแน่ใจว่าเป็นไฟล์
เริ่มต้นด้วย Python 3.4 pathlibโมดูลนำเสนอวิธีการเชิงวัตถุ (backported pathlib2ใน Python 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(strict=True)ในtryบล็อก:
try:
my_abs_path = my_file.resolve(strict=True)
except FileNotFoundError:
# doesn't exist
else:
# exists
FileNotFoundErrorมีการนำมาใช้ใน Python 3 หากคุณต้องการรองรับ Python 2.7 และ Python 3 คุณสามารถใช้IOErrorแทน ( FileNotFoundErrorคลาสย่อยใด) stackoverflow.com/a/21368457/1960959
open('file', 'r+')) แล้วหาทางจบ
คุณมีos.path.existsฟังก์ชั่น:
import os.path
os.path.exists(file_path)
สิ่งนี้จะส่งคืนTrueทั้งไฟล์และไดเรกทอรี แต่คุณสามารถใช้แทนได้
os.path.isfile(file_path)
เพื่อทดสอบว่าเป็นไฟล์เฉพาะหรือไม่ มันติดตาม symlinks
ซึ่งแตกต่างจากisfile(), exists()จะกลับTrueไดเรกทอรี ดังนั้นขึ้นอยู่กับว่าคุณต้องการเพียงไฟล์ธรรมดาหรือยังไดเรกทอรีที่คุณจะใช้หรือisfile() exists()นี่คือเอาท์พุท REPL แบบง่าย ๆ :
>>> os.path.isfile("/etc/password.txt")
True
>>> os.path.isfile("/etc")
False
>>> os.path.isfile("/does/not/exist")
False
>>> os.path.exists("/etc/password.txt")
True
>>> os.path.exists("/etc")
True
>>> os.path.exists("/does/not/exist")
False
import os.path
if os.path.isfile(filepath):
ใช้os.path.isfile()กับos.access():
import os
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")
os.access()จะส่งคืนค่าเท็จ
import osคุณไม่จำเป็นต้องอีกครั้งขณะที่มันมีอยู่แล้วเป็นส่วนหนึ่งของimport os.path osคุณเพียงแค่ต้องนำเข้าos.pathถ้าคุณจะใช้ฟังก์ชั่นจากos.pathและไม่ได้มาจากosตัวเองเพื่อนำเข้าสิ่งเล็ก ๆ แต่เมื่อคุณใช้os.accessและos.R_OKการนำเข้าที่สองไม่จำเป็น
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
แม้ว่าวิธีที่เป็นไปได้เกือบทุกอย่างจะมีการระบุไว้ใน (อย่างน้อยหนึ่งใน) คำตอบที่มีอยู่ (เช่นสิ่งที่ระบุเฉพาะPython 3.4ถูกเพิ่ม) ฉันจะพยายามจัดกลุ่มทุกอย่างด้วยกัน
หมายเหตุ : รหัสห้องสมุดPythonมาตรฐานทุกชิ้นที่ฉันจะโพสต์เป็นของรุ่น3.5.3 3.5.3
คำแถลงปัญหา :
แนวทางแก้ไขที่เป็นไปได้ :
[Python 3]: 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เป็นเพียงลอง / ยกเว้นบล็อกรอบ[Python 3]: os สถิติ ( เส้นทาง, *, dir_fd = ไม่มี follow_symlinks = True ) ดังนั้นรหัสของคุณคือลอง / ยกเว้นฟรี แต่ลดลงในกรอบที่มี (อย่างน้อย) หนึ่งบล็อคดังกล่าว นอกจากนี้ยังใช้กับ funcs อื่น ๆ ( รวมถึง os.path.isfile )
1.1 [Python 3]: เส้นทาง 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[Python 3]: ด้วยผู้จัดการบริบทคำสั่ง ทั้ง:
สร้างหนึ่ง:
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 ...)
และการใช้งานของมัน - ฉันจะทำซ้ำos.path.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ใช้[Python 3]: contextlib ปราบปราม ( * ข้อยกเว้น ) - ซึ่งได้รับการออกแบบมาโดยเฉพาะสำหรับการเลือกข้อยกเว้น
แต่พวกเขาดูเหมือนจะห่อมากกว่าลอง / ยกเว้น / อื่น ๆ / ในที่สุดบล็อกเป็น[หลาม 3]: ผู้ที่มีงบฯ :
วิธีนี้ช่วยให้ลอง ... ยกเว้น ... ในที่สุดรูปแบบการใช้งานจะถูกห่อหุ้มเพื่อนำมาใช้ใหม่ได้สะดวก
ฟังก์ชันการแวะผ่านของระบบไฟล์ (และค้นหาผลลัพธ์สำหรับรายการที่ตรงกัน)
[Python 3]: ระบบปฏิบัติการ listdir ( path = '.' ) (หรือ[Python 3]: os. scandir ( path = '.' )บนPython v 3.5 +, backport: [PyPI]: scandir )
ภายใต้ประทุนใช้ทั้งสอง:
ผ่าน[GitHub]: python / cpython - (หลัก) cpython / Modules / posixmodule.c
การใช้scandir ()แทนที่จะเป็นlistdir ()สามารถเพิ่มประสิทธิภาพของโค้ดที่ต้องการข้อมูลประเภทไฟล์หรือข้อมูลแอตทริบิวต์ไฟล์ได้อย่างมีนัยสำคัญเนื่องจากอ็อบเจ็กต์ os.DirEntryจะเปิดเผยข้อมูลนี้หากระบบปฏิบัติการจัดเตรียมไว้เมื่อสแกนไดเรกทอรี เมธอด os.DirEntryทั้งหมดอาจทำการเรียกระบบ แต่is_dir ()และis_file ()มักจะต้องการการเรียกใช้ระบบสำหรับลิงก์สัญลักษณ์เท่านั้น os.DirEntry.stat ()ต้องมีการเรียกระบบบนยูนิกซ์เสมอ แต่ต้องการเพียงหนึ่งสำหรับลิงก์สัญลักษณ์บน Windows
os.listdir( os.scandirเมื่อมี)glob.glob)
os.listdir
เนื่องจากสิ่งเหล่านี้ซ้ำไปซ้ำมาในโฟลเดอร์ (ในกรณีส่วนใหญ่) พวกเขาไม่มีประสิทธิภาพสำหรับปัญหาของเรา (มีข้อยกเว้นเช่นเดียวกับที่ไม่ใช่ wildcarded glob bing - @ShadowRanger ชี้ให้เห็น) ดังนั้นฉันจะไม่ยืนยันพวกเขา ไม่ต้องพูดถึงว่าในบางกรณีอาจจำเป็นต้องดำเนินการกับชื่อไฟล์
[Python 3]: ระบบปฏิบัติการ การเข้าถึง ( เส้นทางโหมด, *, dir_fd = ไม่มี effective_ids = เท็จ follow_symlinks = True )ที่มีพฤติกรรมอยู่ใกล้กับos.path.exists(ที่จริงมันเป็นที่กว้างขึ้นส่วนใหญ่เป็นเพราะ 2 ครั้งอาร์กิวเมนต์)
... ทดสอบว่าผู้ใช้กล่าวอ้างมีการเข้าถึงที่ระบุเพื่อเส้นทาง โหมดควรเป็นF_OKเพื่อทดสอบการมีอยู่ของเส้นทาง ...
os.access("/tmp", os.F_OK)
ตั้งแต่ผมยังทำงานในCผมใช้วิธีนี้เช่นกันเพราะภายใต้ประทุนมันเรียกพื้นเมืองAPI s (อีกครั้งผ่านทาง"$ {} PYTHON_SRC_DIR /Modules/posixmodule.c" ) แต่มันยังเปิดประตูสำหรับการที่เป็นไปได้ของผู้ใช้ ข้อผิดพลาดและไม่ใช่Python ic เหมือนกับรุ่นอื่น ดังนั้นตามที่ @AaronHall ชี้ให้เห็นอย่างถูกต้องอย่าใช้มันยกเว้นว่าคุณรู้ว่าคุณกำลังทำอะไรอยู่:
หมายเหตุ : การเรียกAPI เนทีฟ s ยังสามารถทำได้ผ่าน[Python 3]: ctypes - ไลบรารีฟังก์ชันต่างประเทศสำหรับ Pythonแต่โดยส่วนใหญ่แล้วจะซับซ้อนกว่า
( เฉพาะWin ): ตั้งแต่vcruntime * ( msvcr * ) .dllส่งออก[MS.Docs]: _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.notexist", os.F_OK) -1
หมายเหตุ :
os.F_OKในการโทร แต่นั่นเป็นเพียงเพื่อความชัดเจน (ค่าของมันคือ0 )
คู่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"/tmp.notexist", os.F_OK) -1
หมายเหตุ :
แทนที่จะ hardcoding libcเส้นทาง 's ( '/lib/x86_64-linux-gnu/libc.so.6' ) ซึ่งอาจ (และส่วนใหญ่มีแนวโน้มจะ) แตกต่างกันในระบบไม่มี (หรือสตริงว่างเปล่า) สามารถส่งผ่านไปCDLLคอนสตรัค ( ctypes.CDLL(None).access(b"/tmp", os.F_OK)) ตามที่[man7]: DLOPEN (3) :
หากชื่อไฟล์เป็น NULL ดังนั้นหมายเลขอ้างอิงที่ส่งคืนจะเป็นของโปรแกรมหลัก เมื่อได้รับการdlsym () จับนี้จะทำให้การค้นหาสำหรับสัญลักษณ์ในโปรแกรมหลักตามด้วยวัตถุที่ใช้ร่วมกันทั้งหมดที่โหลดโปรแกรมที่เริ่มต้นและวัตถุจากนั้นร่วมกันทั้งหมดโหลดโดยdlopen () กับธงRTLD_GLOBAL
__declspec(dllexport)(ทำไมบนโลกที่บุคคลทั่วไปจะทำเช่นนั้น?) โปรแกรมหลักสามารถโหลดได้ แต่ใช้งานไม่ได้ติดตั้งโมดูลบุคคลที่สามที่มีความสามารถของระบบไฟล์
ส่วนใหญ่แล้วจะใช้วิธีใดวิธีหนึ่งข้างต้น (อาจมีการปรับแต่งเล็กน้อย)
ตัวอย่างหนึ่งจะเป็น (อีกครั้งเฉพาะWin ) [GitHub]: mhammond / pywin32 - Python สำหรับ Windows (pywin32) ส่วนขยายซึ่งเป็นPython wrapper เหนือWINAPI s
แต่เนื่องจากนี่เป็นวิธีแก้ปัญหาฉันจึงหยุดที่นี่
วิธีแก้ปัญหาอื่น (lame) ( gainarie ) คือ (ตามที่ฉันต้องการเรียกว่า) แนวทางsysadmin : ใช้Pythonเป็น wrapper เพื่อรันคำสั่งเชลล์
ชนะ :
(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
บรรทัดล่างสุด :
บันทึกสุดท้าย :
glob.iglob(และglob.globเช่นกัน) ขึ้นอยู่กับos.scandirดังนั้นตอนนี้มันขี้เกียจ หากต้องการได้รับความนิยมครั้งแรกในไดเรกทอรีของไฟล์ 10M คุณจะสแกนเพียงจนกว่าจะถึงการเข้าชมครั้งแรก และแม้กระทั่ง pre-3.6 หากคุณใช้globวิธีที่ไม่มี wildcard ใด ๆ ฟังก์ชั่นนั้นชาญฉลาด: มันรู้ว่าคุณสามารถกดได้เพียงครั้งเดียวเท่านั้นดังนั้นมันos.path.isdiros.path.lexistsจึงทำให้การหมุนเป็นวงกลมง่ายขึ้นหรือเพียงแค่ (ขึ้นอยู่กับเส้นทางที่สิ้นสุด/)
os.path.isdirหรือos.path.lexistเนื่องจากมันเป็นการเรียกฟังก์ชั่น การดำเนินการก่อนที่จะตัดสินใจเส้นทางที่มีประสิทธิภาพเป็นไปได้ แต่ไม่มีการเรียกระบบเพิ่มเติมหรืองาน I / O ซึ่งเป็นคำสั่งของขนาดช้าลง)
นี่เป็นวิธีที่ง่ายที่สุดในการตรวจสอบว่ามีไฟล์อยู่หรือไม่ เพียงเพราะไฟล์ที่มีอยู่เมื่อคุณตรวจสอบไม่ได้รับประกันว่าจะมีเมื่อคุณต้องการที่จะเปิด
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")
งูหลาม 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
ชอบคำสั่งลอง ถือว่าเป็นสไตล์ที่ดีกว่าและหลีกเลี่ยงสภาพการแข่งขัน
อย่าใช้คำพูดของฉันมัน มีการสนับสนุนมากมายสำหรับทฤษฎีนี้ นี่คือสองสาม:
try...exceptไม่ได้ช่วยแก้ปัญหาว่าปัญหาอยู่แล้ว
except:clause จะทำให้ข้อยกเว้นที่เกิดขึ้นในส่วนนี้ของรหัสของคุณจะทำให้เกิดข้อความสับสน การประมวลผลของคนแรก.)
ฉันจะตรวจสอบว่ามีไฟล์อยู่หรือไม่โดยใช้ Python โดยไม่ต้องใช้คำสั่ง try
ตอนนี้มีให้ตั้งแต่ Python 3.4 นำเข้าและสร้างอินสแตนซ์Pathวัตถุด้วยชื่อไฟล์และตรวจสอบis_fileวิธีการ (โปรดทราบว่าสิ่งนี้จะคืนค่า True สำหรับ symlink ที่ชี้ไปที่ไฟล์ปกติเช่นกัน):
>>> from pathlib import Path
>>> Path('/').is_file()
False
>>> Path('/initrd.img').is_file()
True
>>> Path('/doesnotexist').is_file()
False
หากคุณใช้ Python 2 คุณสามารถย้อนกลับโมดูล pathlib จาก pypi pathlib2หรือตรวจสอบisfileจากos.pathโมดูลได้:
>>> import os
>>> os.path.isfile('/')
False
>>> os.path.isfile('/initrd.img')
True
>>> os.path.isfile('/doesnotexist')
False
ตอนนี้อาจเป็นคำตอบที่ดีที่สุดในทางปฏิบัติตรงนี้ แต่ก็มีความเป็นไปได้ที่สภาพการแข่งขัน (ขึ้นอยู่กับสิ่งที่คุณพยายามจะทำให้สำเร็จ) และความจริงที่ว่าการใช้งานพื้นฐานนั้นใช้ a tryแต่ Python ใช้tryทุกที่
เนื่องจาก Python ใช้tryทุกที่จึงไม่มีเหตุผลที่จะหลีกเลี่ยงการนำไปใช้งาน
แต่ส่วนที่เหลือของคำตอบนี้พยายามพิจารณาข้อแม้เหล่านี้
มีตั้งแต่ Python 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จัดการบริบท
suppressPython 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ละเอียดมากกว่าด้วย ฉันเชื่อว่านี่เป็นคำตอบเดียวที่ไม่ได้ใช้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)
จากเอกสาร :
os.path.isfile(path)ส่งคืน True ถ้าเส้นทางเป็นไฟล์ปกติที่มีอยู่ นี่ตามลิงก์สัญลักษณ์ดังนั้นทั้งสอง
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
พร้อมใช้งานสำหรับ Unix และ Windows os.accessแต่การใช้งานคุณต้องผ่านการตั้งค่าสถานะและจะไม่แยกความแตกต่างระหว่างไฟล์และไดเรกทอรี สิ่งนี้ใช้ในการทดสอบว่าผู้ใช้ที่มีการเรียกใช้จริงมีการเข้าถึงในสภาพแวดล้อมที่มีสิทธิ์สูงหรือไม่:
import os
os.access(path, os.F_OK)
isfileนอกจากนี้ยังได้รับความทุกข์จากปัญหาเดียวกันสภาพการแข่งขันที่เป็น จากเอกสาร :
หมายเหตุ: การใช้ access () เพื่อตรวจสอบว่าผู้ใช้ได้รับอนุญาตเช่นเปิดไฟล์ก่อนที่จะใช้ 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:
โดยส่วนตัวแล้วฉันชอบอันนี้เพราะภายใต้ประทุนเรียกว่าเนทิฟ API (ผ่าน "$ {PYTHON_SRC_DIR} /Modules/posixmodule.c") แต่มันยังเปิดประตูสำหรับข้อผิดพลาดที่อาจเกิดขึ้นกับผู้ใช้ :
คำตอบนี้บอกว่าชอบวิธีการที่ไม่มีข้อผิดพลาดและไม่มีข้อผิดพลาดโดยไม่มีเหตุผล ดูเหมือนว่าจะกระตุ้นให้ผู้ใช้ใช้ API ระดับต่ำโดยไม่เข้าใจ
นอกจากนี้ยังสร้างตัวจัดการบริบทซึ่งกลับมาโดยไม่มีเงื่อนไขTrueช่วยให้ข้อยกเว้นทั้งหมด (รวมถึงKeyboardInterruptและSystemExit!) ผ่านไปอย่างเงียบ ๆ ซึ่งเป็นวิธีที่ดีในการซ่อนข้อบกพร่อง
สิ่งนี้ดูเหมือนจะกระตุ้นให้ผู้ใช้ยอมรับการปฏิบัติที่ไม่ดี
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ช่วยให้นำทางและดำเนินการมาตรฐานกับระบบปฏิบัติการของคุณได้ง่ายขึ้น
สำหรับการอ้างอิงดูที่วิธีตรวจสอบว่ามีไฟล์อยู่ด้วย Python หรือไม่
หากคุณต้องการการดำเนินงานในระดับสูง, shutilการใช้งาน
os.path.existsคืนค่าจริงสำหรับสิ่งที่ไม่ใช่ไฟล์เช่นไดเรกทอรี สิ่งนี้ให้ผลบวกที่ผิดพลาด ดูคำตอบอื่น ๆ os.path.isfileที่แนะนำ
การทดสอบสำหรับไฟล์และโฟลเดอร์ที่มีos.path.isfile(), os.path.isdir()และos.path.exists()
สมมติว่า "path" เป็นพา ธ ที่ถูกต้องตารางนี้แสดงสิ่งที่ส่งคืนโดยแต่ละฟังก์ชันสำหรับไฟล์และโฟลเดอร์:
คุณสามารถทดสอบได้ว่าไฟล์เป็นไฟล์ประเภทหนึ่งที่ใช้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
ในปี 2559 วิธีที่ดีที่สุดยังคงใช้อยู่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():
...
pathlibเป็นวิธีการแก้ปัญหา OOP ของไพ ธ อนสำหรับเส้นทาง คุณสามารถทำอะไรได้มากกว่านี้อีกแล้ว หากคุณเพียงแค่ต้องตรวจสอบการดำรงอยู่ของข้อได้เปรียบไม่ใหญ่มาก
ดูเหมือนจะไม่มีความแตกต่างในการใช้งานที่มีความหมายระหว่างลอง / ยกเว้นและ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'
หากคุณต้องการล็อคไฟล์นั่นเป็นเรื่องอื่น
os.path.existsคืนค่าจริงสำหรับสิ่งที่ไม่ใช่ไฟล์เช่นไดเรกทอรี สิ่งนี้ให้ผลบวกที่ผิดพลาด ดูคำตอบอื่น ๆ os.path.isfileที่แนะนำ
filepathมีจังหวะเวลาที่เหมาะสมและBAMคุณเขียนทับไฟล์เป้าหมาย คุณควรทำopen(filepath, 'wx')ในtry...exceptบล็อกเพื่อหลีกเลี่ยงปัญหา
OSErrorถ้าfilepath + '.old'มีอยู่แล้ว: "บน Windows หาก dst มีอยู่แล้ว OSError จะเพิ่มขึ้นแม้ว่าจะเป็นไฟล์ แต่อาจไม่มีวิธีในการเปลี่ยนชื่ออะตอมมิกเมื่อ dst ตั้งชื่อไฟล์ที่มีอยู่ "
os.replaceทำการแทนที่ไฟล์ปลายทางได้อย่างเงียบ ๆ (มันเหมือนกับos.renameพฤติกรรมของ Linux) (จะมีข้อผิดพลาดเฉพาะเมื่อชื่อปลายทางนั้นมีอยู่และเป็นไดเรกทอรี) คุณติดอยู่ที่ 2.x แต่ผู้ใช้ Py3 มีตัวเลือกที่ดีมาหลายปีแล้ว
renameตัวอย่างเช่นมันก็ยังคงควรจะทำด้วย/try (หรือPython สมัยใหม่) เป็นอะตอม ทำให้มันตรวจสอบแล้วเปลี่ยนชื่อแนะนำการแข่งขันที่ไม่จำเป็นและการเรียกระบบเพิ่มเติม เพิ่งทำexceptos.renameos.replacetry: os.replace(filepath, filepath + '.old') except OSError: pass
คุณสามารถลอง (ปลอดภัยกว่า):
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] ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว: 'Anything.txt')
จากนั้นขึ้นอยู่กับผลลัพธ์โปรแกรมของคุณสามารถทำงานต่อจากที่นั่นหรือคุณสามารถโค้ดเพื่อหยุดถ้าคุณต้องการ
try
แม้ว่าฉันมักจะแนะนำให้ใช้tryและexceptข้อความต่างๆต่อไปนี้เป็นความเป็นไปได้บางอย่างสำหรับคุณ (รายการโปรดส่วนตัวของฉันกำลังใช้os.access):
ลองเปิดไฟล์:
การเปิดไฟล์จะตรวจสอบการมีอยู่ของไฟล์เสมอ คุณสามารถสร้างฟังก์ชั่นได้เช่น:
def File_Existence(filepath):
f = open(filepath)
return True
ถ้าเป็นเท็จมันจะหยุดการทำงานด้วย IOError หรือ 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ใช้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ใช้os.access(path, mode):
วิธีนี้จะตรวจสอบว่าคุณมีสิทธิ์เข้าถึงไฟล์หรือไม่ มันจะตรวจสอบสิทธิ์ ขึ้นอยู่กับเอกสาร os.py พิมพ์os.F_OKมันจะตรวจสอบการมีอยู่ของเส้นทาง อย่างไรก็ตามการใช้สิ่งนี้จะสร้างช่องโหว่ด้านความปลอดภัยเนื่องจากบางคนสามารถโจมตีไฟล์ของคุณโดยใช้เวลาระหว่างการตรวจสอบการอนุญาตและการเปิดไฟล์ คุณควรไปที่การเปิดไฟล์โดยตรงแทนที่จะตรวจสอบการอนุญาต ( EAFPเทียบกับ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)เพื่อให้คุณสามารถระบุปัญหาของคุณได้ ฉันหวังว่ามันจะช่วย! :)
วันที่: 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')
ฉันทำ cheatsheet ครบถ้วนสมบูรณ์สำหรับการอ้างอิงของคุณ:
#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']}
หากไฟล์สำหรับเปิดคุณสามารถใช้หนึ่งในเทคนิคต่อไปนี้:
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!')
UPDATE
เพียงเพื่อหลีกเลี่ยงความสับสนและตามคำตอบที่ฉันได้คำตอบปัจจุบันจะค้นหาไฟล์หรือไดเรกทอรีที่มีชื่อที่กำหนด
os.path.existsคืนค่าจริงสำหรับสิ่งที่ไม่ใช่ไฟล์เช่นไดเรกทอรี สิ่งนี้ให้ผลบวกที่ผิดพลาด ดูคำตอบอื่น ๆ os.path.isfileที่แนะนำ
นอกจากนี้os.access():
if os.access("myfile", os.R_OK):
with open("myfile") as fp:
return fp.read()
กำลังR_OK, W_OKและ, X_OKแฟล็กเพื่อทดสอบการอนุญาต ( doc )
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 จะถูกยกขึ้นหากไฟล์มีอยู่ แต่ผู้ใช้ไม่ได้รับอนุญาตให้อ่าน
หากคุณนำเข้า NumPy แล้วเพื่อวัตถุประสงค์อื่น ๆ แล้วมีความจำเป็นต้องนำเข้าห้องสมุดอื่น ๆ เช่นpathlib, os, pathsฯลฯ
import numpy as np
np.DataSource().exists("path/to/your/file")
สิ่งนี้จะคืนค่าจริงหรือเท็จตามการมีอยู่ของมัน
try:คุณสามารถเขียนข้อเสนอแนะของไบรอันได้โดยไม่ต้อง
from contextlib import suppress
with suppress(IOError), open('filename'):
process()
suppressเป็นส่วนหนึ่งของ Python 3.4 ในรุ่นเก่าคุณสามารถเขียนการปราบปรามของคุณเองได้อย่างรวดเร็ว:
from contextlib import contextmanager
@contextmanager
def suppress(*exceptions):
try:
yield
except exceptions:
pass
ฉันเป็นผู้เขียนของแพ็คเกจที่มีมานานประมาณ 10 ปีและมีฟังก์ชั่นที่ตอบคำถามนี้โดยตรง โดยทั่วไปถ้าคุณอยู่ในระบบที่ไม่ใช่ Windows จะใช้ในการเข้าถึงPopen findอย่างไรก็ตามถ้าคุณใช้ Windows มันจะทำซ้ำfindกับระบบไฟล์ที่มีประสิทธิภาพ
รหัสที่ตัวเองไม่ได้ใช้tryบล็อก ... ยกเว้นในการกำหนดระบบปฏิบัติการและทำให้พวงมาลัยคุณไป "ยูนิกซ์" สไตล์หรือมือfind 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
คุณสามารถทำตามสามวิธีต่อไปนี้:
หมายเหตุ 1:
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+, ติดตั้งได้กับ pip สำหรับงูหลาม 2)
from pathlib import Path
Path(filename).exists()
การเพิ่มการเปลี่ยนแปลงอีกเล็กน้อยซึ่งไม่ได้สะท้อนให้เห็นอย่างชัดเจนในคำตอบอื่น ๆ
นี้จะจัดการกับกรณีของการ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
การเพิ่มชุดตัวเลือกตามข้อเสนอแนะจาก Shahbaz
def file_exists(file_path):
if not file_path:
return False
else:
return os.path.isfile(file_path)
การเพิ่มตัวแปรตามคำแนะนำจาก Peter Wood
def file_exists(file_path):
return file_path and os.path.isfile(file_path):
if (x) return true; else return false;return xเป็นจริงเพียง return os.path.isfile(file_path)สี่บรรทัดสุดท้ายของคุณจะกลายเป็น return file_path and os.path.isfile(file_path)ในขณะที่เรากำลังที่จะฟังก์ชั่นทั้งสามารถประยุกต์เป็น
return x if (x)Python จะพิจารณาสตริงว่างเปล่า False ซึ่งในกรณีนี้เราจะส่งคืนสตริงว่างแทนที่จะเป็นบูล วัตถุประสงค์ของฟังก์ชั่นนี้คือส่งคืนบูลเสมอ
xนี้os.path.isfile(..)มันเป็นบูลที่มีอยู่แล้ว
os.path.isfile(None)เพิ่มข้อยกเว้นซึ่งเป็นสาเหตุที่ฉันเพิ่มการตรวจสอบถ้า ฉันอาจจะห่อมันด้วยการลอง / ยกเว้นแทน แต่ฉันรู้สึกว่ามันชัดเจนกว่านี้
return file_path and os.path.isfile(file_path)
ต่อไปนี้เป็นคำสั่ง Python 1 บรรทัดสำหรับสภาพแวดล้อมบรรทัดคำสั่ง Linux ฉันพบว่ามันมีประโยชน์มากเพราะฉันไม่ใช่คนทุบตีที่ร้อนแรง
python -c "import os.path; print os.path.isfile('/path_to/file.xxx')"
ฉันหวังว่านี้จะเป็นประโยชน์.
[ -f "${file}" ] && echo "file found" || echo "file not found"(ซึ่งเหมือนกับif [ ... ]; then ...; else ...; fi)
คุณสามารถใช้ไลบรารี "OS" ของ Python ได้:
>>> import os
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.txt")
True
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.tx")
False
os.path.existsคืนค่าจริงสำหรับสิ่งที่ไม่ใช่ไฟล์เช่นไดเรกทอรี สิ่งนี้ให้ผลบวกที่ผิดพลาด ดูคำตอบอื่น ๆ os.path.isfileที่แนะนำ
existsถือว่าใช้ได้ หากเป้าหมายคือการตรวจสอบว่ามีความปลอดภัยในการเปิดไฟล์ที่มีอยู่สันนิษฐานว่าการวิจารณ์นั้นเป็นธรรมและมีอยู่จริงนั้นไม่แม่นยำเพียงพอ น่าเสียดายที่ OP ไม่ได้ระบุว่าเป็นเป้าหมายที่ต้องการ (และอาจจะไม่ทำอีกต่อไป)
ฉันจะตรวจสอบว่ามีไฟล์อยู่โดยไม่ใช้คำสั่ง try ได้อย่างไร
ในปี 2559 นี้ยังคงเป็นวิธีที่ง่ายที่สุดในการตรวจสอบว่ามีทั้งไฟล์อยู่หรือไม่และเป็นไฟล์:
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.path
def isReadableFile(file_path, file_name):
full_path = file_path + "/" + file_name
try:
if not os.path.exists(file_path):
print "File path is invalid."
return False
elif not os.path.isfile(full_path):
print "File does not exist."
return False
elif not os.access(full_path, os.R_OK):
print "File cannot be read."
return False
else:
print "File can be read."
return True
except IOError as ex:
print "I/O error({0}): {1}".format(ex.errno, ex.strerror)
except Error as ex:
print "Error({0}): {1}".format(ex.errno, ex.strerror)
return False
#------------------------------------------------------
path = "/usr/khaled/documents/puzzles"
fileName = "puzzle_1.txt"
isReadableFile(path, fileName)
isReadableFile(path,fileName)จะกลับมาTrueถ้าไฟล์สามารถเข้าถึงได้และสามารถอ่านได้โดยกระบวนการ \ program \ thread