จะละเว้นไฟล์ที่ซ่อนโดยใช้ os.listdir () ได้อย่างไร?


88

สคริปต์ python ของฉันเรียกใช้os.listdir(path)โดยที่พา ธ เป็นคิวที่มีไฟล์เก็บถาวรที่ฉันต้องจัดการทีละรายการ

array.pop(0)ปัญหาคือว่าฉันได้รับรายการในอาร์เรย์และจากนั้นผมก็ทำง่ายๆ มันทำงานได้ดีจนกระทั่งฉันวางโครงการไว้ในการโค่นล้ม ตอนนี้ฉันได้รับ.svnโฟลเดอร์ในอาร์เรย์ของฉันและแน่นอนว่ามันทำให้แอปพลิเคชันของฉันพัง

นี่คือคำถามของฉัน: มีฟังก์ชั่นที่ละเว้นไฟล์ที่ซ่อนอยู่เมื่อดำเนินการos.listdir()และถ้าไม่ใช่วิธีที่ดีที่สุดคืออะไร?


คุณอาจต้องการหลีกเลี่ยงโฟลเดอร์ด้วยos.path.isdir()
HashRocketSyntax

คำตอบ:


103

คุณสามารถเขียนด้วยตัวคุณเอง:

def listdir_nohidden(path):
    for f in os.listdir(path):
        if not f.startswith('.'):
            yield f

หรือคุณสามารถใช้glob :

def listdir_nohidden(path):
    return glob.glob(os.path.join(path, '*'))

'.'ทั้งสองเหล่านี้จะไม่สนใจทุกไฟล์ที่เริ่มต้นด้วย


1
ฟังก์ชั่นที่นำเสนอlistdir_nohiddenไม่เข้ากันได้กับos.listdirเนื่องจากการใช้yieldทำให้เป็นเครื่องกำเนิดไฟฟ้า แต่ควรรันผ่านรายการผลลัพธ์จากos.listdirและลบรายการที่ขึ้นต้นด้วย "."
Milo Wielondek

3
@ 0sh: ทำไมต้องเอาของเข้าที่? เพียงแค่กำหนดฟังก์ชั่นใหม่ที่ไม่และฟังก์ชั่นใหม่เป็นว่าเข้ากันได้กับlist(listdir_nohidden(path)) os.listdir
ยกเลิก

50

นี่เป็นคำถามเก่า แต่ดูเหมือนว่าจะไม่มีคำตอบที่ชัดเจนในการใช้ list compleance ดังนั้นฉันจึงเพิ่มที่นี่เพื่อความสมบูรณ์:

[f for f in os.listdir(path) if not f.startswith('.')]

ในฐานะที่เป็นหมายเหตุด้านข้างสถานะเอกสารlistdirจะส่งคืนผลลัพธ์ใน "ลำดับตามอำเภอใจ" แต่กรณีการใช้งานทั่วไปคือการจัดเรียงตามตัวอักษร หากคุณต้องการให้เนื้อหาไดเรกทอรีเรียงตามตัวอักษรโดยไม่คำนึงถึงการใช้อักษรตัวพิมพ์ใหญ่คุณสามารถใช้:

sorted([f for f in os.listdir('./')], key=lambda f: f.lower())

5
key=lambda f: f.lower()สามารถเขียนได้โดยไม่ต้องแลมkey=str.lower
Jean-François Fabre

2
ในการรวมทั้งสองอย่าง:sorted([f for f in os.listdir('./') if not f.startswith('.')], key=str.lower)
Robert

19

บน Windows, Linux และ OS X:

if os.name == 'nt':
    import win32api, win32con


def folder_is_hidden(p):
    if os.name== 'nt':
        attribute = win32api.GetFileAttributes(p)
        return attribute & (win32con.FILE_ATTRIBUTE_HIDDEN | win32con.FILE_ATTRIBUTE_SYSTEM)
    else:
        return p.startswith('.') #linux-osx

2
ควรทำงานบน Mac ไฟล์ที่ซ่อนอยู่เริ่มต้นด้วย "." เช่นกัน.
Verena Haunschmid

2
นี่เป็นคำตอบแบบพกพาเพียงคำตอบที่ยอดเยี่ยม แต่คำตอบอื่น ๆ มีกระดาษห่อหุ้มเต็มรูปแบบสำหรับ os.listdir ดังนั้น ...[f for f in os.listdir(path) if not folder_is_hidden(f)]
SensorSmith

15

Joshmaker มีคำตอบที่เหมาะสมสำหรับคำถามของคุณ
จะละเว้นไฟล์ที่ซ่อนโดยใช้ os.listdir () ได้อย่างไร?

อย่างไรก็ตามใน Python 3 ขอแนะนำให้ใช้ pathlib แทน os

from pathlib import Path 
visible_files = [
    file for file in Path(".").iterdir() if not file.name.startswith(".")
]


6

ฉันคิดว่ามันเป็นงานที่มากเกินไปที่จะทำทุกอย่างให้เป็นวง ฉันต้องการสิ่งที่ง่ายกว่านี้:

lst = os.listdir(path)
if '.DS_Store' in lst:
    lst.remove('.DS_Store')

หากไดเร็กทอรีมีไฟล์ที่ซ่อนอยู่มากกว่าหนึ่งไฟล์สิ่งนี้สามารถช่วยได้:

all_files = os.popen('ls -1').read()
lst = all_files.split('\n')

เพื่อความเป็นอิสระของแพลตฟอร์มตามที่ @Josh กล่าวว่า glob ทำงานได้ดี:

import glob
glob.glob('*')

ที่ทำงานเฉพาะถ้าคุณมีหนึ่งไฟล์ที่ซ่อนอยู่และคุณทราบชื่อของมัน จะเกิดอะไรขึ้นถ้าไดเรกทอรีมีไฟล์ที่ซ่อนอยู่หลายสิบไฟล์พร้อมชื่อที่คุณไม่สามารถทราบล่วงหน้าได้
FeRD

สวัสดี @FeRD ใช่ เมื่อฉันทำการประมวลผลแบทช์ / แบ็ตช์บนเครื่อง Mac ฉันจะใส่ไฟล์ทั้งหมดในโฟลเดอร์ใหม่และ.DS_Storeสร้างขึ้นโดยอัตโนมัติ เมื่อฉัน zip ไฟล์ทั้งหมดและส่งไป.DS_Storeยังเซิร์ฟเวอร์ก็จะถูกเพิ่มด้วย หากมีไฟล์ต่างๆที่ซ่อนอยู่คุณสามารถลองos.system('ls -1')
ผู้ใช้ 923227

ไม่ใช่ข้ามแพลตฟอร์ม os.popen('ls -1').read()จะไม่ทำงานบน Windows os.listdir()นั่นเป็นจุดรวมของ
FeRD

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.