نظام التشغيل.المشي من دون البحث في أدلة أدناه
سؤال
كيف يمكنني الحد os.walk
إلى العودة فقط الملفات في الدليل الأول تقديم ذلك ؟
def _dir_list(self, dir_name, whitelist):
outputList = []
for root, dirs, files in os.walk(dir_name):
for f in files:
if os.path.splitext(f)[1] in whitelist:
outputList.append(os.path.join(root, f))
else:
self._email_to_("ignore")
return outputList
المحلول
استخدم وظيفة walklevel
.
import os
def walklevel(some_dir, level=1):
some_dir = some_dir.rstrip(os.path.sep)
assert os.path.isdir(some_dir)
num_sep = some_dir.count(os.path.sep)
for root, dirs, files in os.walk(some_dir):
yield root, dirs, files
num_sep_this = root.count(os.path.sep)
if num_sep + level <= num_sep_this:
del dirs[:]
وهو يعمل تماما مثل os.walk
، ولكن يمكنك تمريرها معلمة level
التي تشير إلى مدى عمق سيذهب العودية.
نصائح أخرى
لا تستخدم os.walk.
مثال:
import os
root = "C:\\"
for item in os.listdir(root):
if os.path.isfile(os.path.join(root, item)):
print item
أعتقد أن الحل هو في الواقع بسيط جدا.
استخدام
break
أن تفعل سوى التكرار الأول من حلقة ، يجب أن تكون هناك طريقة أكثر أناقة.
for root, dirs, files in os.walk(dir_name):
for f in files:
...
...
break
...
في المرة الأولى التي تتصل نظام التشغيل.سيرا على الأقدام ، فإنه يعود التوليب في الدليل الحالي ثم في الحلقة القادمة محتويات دليل المقبل.
خذ الأصلي النصي فقط إضافة كسر.
def _dir_list(self, dir_name, whitelist):
outputList = []
for root, dirs, files in os.walk(dir_name):
for f in files:
if os.path.splitext(f)[1] in whitelist:
outputList.append(os.path.join(root, f))
else:
self._email_to_("ignore")
break
return outputList
وهذا الاقتراح لاستخدام listdir
هو فكرة جيدة. الإجابة المباشرة على سؤالك في بايثون 2 هي root, dirs, files = os.walk(dir_name).next()
.
وهذا يعادل بيثون 3 بناء الجملة root, dirs, files = next(os.walk(dir_name))
هل يمكن استخدام os.listdir()
التي ترجع قائمة بأسماء (لكل من الملفات والدلائل) في دليل معين. إذا كنت بحاجة إلى التمييز بين الملفات والدلائل، والدعوة os.stat()
على كل اسم.
إذا كان لديك متطلبات أكثر تعقيدا من مجرد دليل العلوي (على سبيل المثال تجاهل VCS تطبيق الاستعراض المفصل الخ)، ويمكنك أيضا تعديل قائمة الدلائل لمنع os.walk recursing من خلالهم.
وأي:
def _dir_list(self, dir_name, whitelist):
outputList = []
for root, dirs, files in os.walk(dir_name):
dirs[:] = [d for d in dirs if is_good(d)]
for f in files:
do_stuff()
ملحوظة - أن يكون حريصا على التحور القائمة، بدلا من مجرد rebind ذلك. من الواضح os.walk لا تعرف عن إعادة الربط الخارجي.
ونفس الفكرة مع listdir
، ولكن أقصر:
[f for f in os.listdir(root_dir) if os.path.isfile(os.path.join(root_dir, f))]
for path, dirs, files in os.walk('.'):
print path, dirs, files
del dirs[:] # go only one level deep
ورأى مثل رمي بلدي 2 بنس في.
baselevel = len(rootdir.split("\\"))
for subdirs, dirs, files in os.walk(rootdir):
curlevel = len(subdirs.split("\\"))
if curlevel <= baselevel + 1:
[do stuff]
في بيثون 3، وكنت قادرا على القيام بذلك:
import os
dir = "/path/to/files/"
#List all files immediately under this folder:
print ( next( os.walk(dir) )[2] )
#List all folders immediately under this folder:
print ( next( os.walk(dir) )[1] )
هل يمكن أيضا القيام بما يلي:
for path, subdirs, files in os.walk(dir_name):
for name in files:
if path == ".": #this will filter the files in the current directory
#code here
وهذه هي الطريقة I حلها
if recursive:
items = os.walk(target_directory)
else:
items = [next(os.walk(target_directory))]
...
وهناك كمية الصيد عند استخدام listdir. يجب أن يكون os.path.isdir (معرف) مسار مطلق. لاختيار الدلائل تفعله:
for dirname in os.listdir(rootdir):
if os.path.isdir(os.path.join(rootdir, dirname)):
print("I got a subdirectory: %s" % dirname)
والبديل هو تغيير إلى الدليل أن تفعل اختبار دون os.path.join ().
ويمكنك استخدام هذا المقتطف
for root, dirs, files in os.walk(directory):
if level > 0:
# do some stuff
else:
break
level-=1
وإنشاء قائمة يستبعد استخدام fnmatch لتخطي بنية الدليل والقيام بعملية
excludes= ['a\*\b', 'c\d\e']
for root, directories, files in os.walk('Start_Folder'):
if not any(fnmatch.fnmatch(nf_root, pattern) for pattern in excludes):
for root, directories, files in os.walk(nf_root):
....
do the process
....
ونفس ل 'تشمل':
if **any**(fnmatch.fnmatch(nf_root, pattern) for pattern in **includes**):
لماذا لا مجرد استخدام range
وos.walk
جنبا إلى جنب مع zip
؟ ليس الحل الأمثل، ولكن سيعمل أيضا.
وعلى سبيل المثال مثل هذا:
# your part before
for count, (root, dirs, files) in zip(range(0, 1), os.walk(dir_name)):
# logic stuff
# your later part
ويعمل بالنسبة لي على الثعبان 3.
وأيضا: break
هو أبسط راجع للشغل أيضا. (نظرة على الجواب منPieter)
وتغيير طفيف على الجواب اليكس، ولكن باستخدام __next__()
:
وprint(next(os.walk('d:/'))[2])
أو
print(os.walk('d:/').__next__()[2])
ومع [2]
كونها file
في root, dirs, file
المذكورة في إجابات أخرى
منذ بيثون 3.5 يمكنك استخدام os.scandir
بدلا من os.listdir
.بدلا من السلاسل تحصل مكرر من DirEntry
الكائنات في العودة.من مستندات:
باستخدام
scandir()
بدلا منlistdir()
يمكن أن تزيد بشكل كبير من أداء البرمجية التي يحتاج أيضا نوع الملف أو ملف السمة المعلومات ، لأنDirEntry
الكائنات فضح هذه المعلومات إذا كان نظام التشغيل تنص على أنه عند إجراء المسح الضوئي دليل.كلDirEntry
أساليب قد تؤدي استدعاء نظام ، ولكنis_dir()
وis_file()
عادة لا تتطلب سوى استدعاء نظام الرمزية الروابط ؛DirEntry.stat()
دائما يتطلب استدعاء نظام Unix ولكن يتطلب سوى أحد الارتباطات الرمزية على ويندوز.
يمكنك الوصول إلى اسم الكائن عبر DirEntry.name
ثم ما يعادل الناتج من os.listdir
والتغييرات المجلد الجذر لكل os.walk دليل وجدت. I حلالا أن التحقق إذا الجذر == الدليل
def _dir_list(self, dir_name, whitelist):
outputList = []
for root, dirs, files in os.walk(dir_name):
if root == dir_name: #This only meet parent folder
for f in files:
if os.path.splitext(f)[1] in whitelist:
outputList.append(os.path.join(root, f))
else:
self._email_to_("ignore")
return outputList