Is there any significance in the triple underscore in Python?
This was in a script for getting all .txt
files in a directory.
for ___,___,files in os.walk(some_folder):
files[:]=[x for x in files if x.lower().endswith('txt')]
for file in files:
Reading other questions on here a single underscore is normally used for throw away variables, is this use of a triple underscore just bad practice or is there significance to it?
Single, double, triple and, in general, any amount of underscore only names in a script implicitly signifies that the value will not be used (the fact that it isn't given a "name" using any letters signifies this).
This is, of course, not set in stone (that is, Python doesn't treat ___
any differently than a name like foo
) instead it's a convention programmers usually understand and respect.
The single underscore has a purpose only in interactive mode and it's the one that's employed in scripts instead of __
or ___
. Using ___
and __
just look ugly and really are completely unecessary; I can't see why someone would decide to use it over _
; don't copy them and opt for _
when you need to get the same message across.
Like Jim said, the ___
syntax usually means whatever is captured by that name (___
) isn't useful, or is garbage. Take a look at the following example, for the sake of completeness:
I have a folder, test
, with the following structure:
test
subtest1
file1.txt
file2.txt
subtest2
file3.txt
Look what happens when I use os.walk
on test
:
>>> list(os.walk('test'))
[('test', ['subtest1', 'subtest2'], ['.DS_Store']), ('test/subtest1', [], ['file1.txt', 'file2.txt']), ('test/subtest2', [], ['file3.txt'])]
>>> len(list(os.walk('test')))
3
So there are technically three elements in the generator returned by os.walk('test')
. How many elements are within each element, though, since we clearly see some nested data structures?
>>> [len(x) for x in os.walk('test')]
[3, 3, 3]
Okay, there are three subelements in each element of os.walk('test')
. For example, at list(os.walk('test'))[0]
, there is 'test'
(the first element), ['subtest1', 'subtest2']
(the second element), and ['.DS_Store']
(the third and final element). The last element contains the non-directory files in whatever folder is denoted by the first element (so .DS_Store is a file in the test
directory).
Let's get to your for
loop, then (I won't use the underscores yet):
>>> for main_dir, sub_dirs, files in os.walk('test'):
... print("Main directory: ", main_dir)
... print("Sub-directories: ", ', '.join(sub_dirs))
... print("Files: ", ', '.join(files))
...
Main directory: test
Sub-directories: subtest1, subtest2
Files: .DS_Store
Main directory: test/subtest1
Sub-directories:
Files: file1.txt, file2.txt
Main directory: test/subtest2
Sub-directories:
Files: file3.txt
So the for main_dir, sub_dirs, files in os.walk('test')
syntax is really what we call "unpacking." We are assigning to main_dir
the first element in os.walk('test')
, to sub_dirs
the second element, etc. The ___
syntax (which really should be just _
), says to the reader, "Forget about these values; I've named the ones I need." In your case, the code is saying, "Forget about the directories from which these files come; I just want the filenames themselves."
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With