![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 | |
|
Expert Programmer
|
Method not returning?
I wrote a method which is supposed to search a directory (and subdirectories up to 'recurl' levels) for the first instance of a file named 'name', and return the full path to that file.
def findfileswithname(path, name, recurl=4, i=0):
if not os.path.isdir(path): return
for item in os.listdir(path):
itempath = os.path.join(path, item)
if os.path.isdir(itempath) and i < recurl:
findfileswithname(itempath, name, recurl, i+1)
elif item == name:
print 'found it %s' % os.path.join(path, item),
return os.path.join(path, item)
print '.',Quote:
|
|
|
|
|
|
|
#2 |
|
Expert Programmer
|
I managed to sidestep this problem by using os.walk:
filename = 'schedule.xls'
searchdir = 'T:\Test'
for root, dirs, files in os.walk(searchdir):
if filename in files:
result = root + name
break
print result |
|
|
|
|
|
#3 |
|
Programming Guru
![]() Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 4
![]() |
def findfileswithname(path, name, recurl=4, i=0):
if i >= recurl: return
for item in os.listdir(path):
itempath = os.path.join(path, item)
if os.path.isdir(itempath):
found = findfileswithname(itempath, name, recurl, i+1)
if found: return found
elif item == name:
print 'found it %s' % os.path.join(path, item),
return os.path.join(path, item)
print '.',The code in blue I added/changed to fix a small bug (or what I suspect is a bug). The original if statement read, "if itempath is a directory, and the recusive limit has not been met, then do this". This means that the elif would have read: "if itempath is not a directory, or if it is a directory and the recursive limit was not met, and the item is the item we're searching for, then do this." Thus, if the recursive limit was met, then the function would return directories as well as files. The blue code should fix this up. Also, I removed this line of code: if not os.path.isdir(path): return |
|
|
|
|
|
#4 |
|
Expert Programmer
|
Thanks, Arevos. I'm using the code you fixed rather than os.walk() because I can't specify a maximum recursive limit, as far as I know.
|
|
|
|
|
|
#5 |
|
Expert Programmer
|
I have another question. I based the function in my first post on the code for another similar function I wrote, which returns a list of all files with an appropriate extension. However, in this function I don't return the list of files until the very end. Why does this work here when it doesn't in the function I posted previously? Or have I done something wrong here as well?
def findfileswithext(path, exts=NC_EXTENSIONS, recurl=3, i=0, files=[]):
"""Return a list of filepaths to files with an extension in exts
Recurl is the level of recursion, or depth of subdirectories to search"""
if not os.path.isdir(path): return
for item in os.listdir(path):
itempath = os.path.join(path, item)
if os.path.isdir(itempath) and i < recurl:
findfileswithext(itempath, exts, recurl, i+1)
elif os.path.splitext(item)[1] in exts:
files.append(itempath)
return files |
|
|
|
|
|
#6 |
|
Programming Guru
![]() Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 4
![]() |
It works, because the "files" list is constant throughout the recursion. Take a look at this line:
def findfileswithext(path, exts=NC_EXTENSIONS, recurl=3, i=0, files=[]): I'll give you a quick example of this: >>> def foobar(x = []): ... print x ... x.append(len(x)) ... >>> foobar() [] >>> foobar() [0] >>> foobar() [0, 1] >>> foobar() [0, 1, 2] It usually isn't a good idea to use this functionality, however, as it's somewhat confusing. |
|
|
|
|
|
#7 |
|
Programming Guru
![]() Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 4
![]() |
As an aside, there's a lot of common functionality in your two functions that can be abstracted out. If there was a function similar to os.walk, but with a recursive limit, then your functions would be a lot simpler.
Maybe something like this: def limited_walk(path, limit, n = 0):
if n > limit: return
for file in os.listdir(path):
file_path = os.path.join(path, file)
if os.path.isdir(file_path):
for item in limited_walk(file_path, limit, n + 1):
yield item
else:
yield file_path
# Example of use:
for filename in limited_walk("some_directory", 4):
if os.path.basename(filename) == name:
print filename |
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|